Source code for appyter.profiles.default.fields.TextListField

import re
from appyter.fields import Field, FieldConstraintException
from appyter.ext.re import re_full

[docs]class TextListField(Field): ''' Representing a field that accepts a set of strings separated by newlines Be careful with this field, consider defining a constraint regex. ```eval_rst Unlike :class:`appyter.profiles.default.fields.TextField`, this class will return a list and potentially render differently. ``` :param name: (str) A name that will be used to refer to the object as a variable and in the HTML form. :param label: (str) A human readable label for the field for the HTML form :param description: (Optional[str]) A long human readable description for the field for the HTML form :param choices: (Union[List[str], Dict[str, str]]) A set of choices that are available for this field or lookup table mapping from choice label to resulting value :param constraint: (Regex[str]) A regular expression for validating the file name. :param required: (Optional[bool]) Whether or not this field is required (defaults to false) :param default: (List[str]) A default value as an example and for use during prototyping :param examples: (Optional[Dict[str, List[str]]]) Named lists to provide as clickable examples :param hint: (Optional[str]) A hint to put in the field prior to content. :param rows: (Optional[int]) The number of rows (lines) in the textarea :param cols: (Optional[int]) The number of cols (horizontal characters) in the textarea :param section: (Optional[str]) The name of a SectionField for which to nest this field under, defaults to a root SectionField :param value: (INTERNAL Any) The raw value of the field (from the form for instance) :param \**kwargs: Remaining arguments passed down to :class:`appyter.fields.Field`'s constructor. ''' def __init__(self, constraint=r'[^\n]*', hint=None, **kwargs): super().__init__( constraint=constraint, hint=hint, **kwargs, ) @property def raw_value(self): if type(self.args['value']) == str: return list( filter(None, map(str.strip, self.args['value'].splitlines() ) ) ) elif type(self.args['value']) == list or type(self.args['value']) == tuple: return list(self.args['value']) elif self.args['value'] is None: return [] else: return None
[docs] def constraint(self): if not self.raw_value: return not self.args.get('required') else: return all([ re.match(re_full(self.args['constraint']), val) for val in self.raw_value ])
@property def value(self): if not self.constraint(): raise FieldConstraintException( field=self.field, field_name=self.args['name'], value=self.raw_value, ) elif type(self.choices) == dict: return [self.choices[v] for v in self.raw_value] else: return self.raw_value
[docs] def to_jsonschema(self): schema = {'type': 'array', 'items': { 'type': 'string' } } if self.args.get('label'): schema['title'] = self.args['label'] if self.args.get('description'): schema['description'] = self.args['description'] if self.args.get('choices'): schema['items']['enum'] = list(self.args['choices']) if self.args.get('constraint'): schema['items']['pattern'] = re_full(self.args['constraint']) if self.args.get('default'): schema['default'] = self.args['default'] return schema
[docs] def to_cwl(self): schema = super().to_cwl() # NOTE: CWL's array enum is broken upstream # if self.args.get('choices'): # if self.args.get('required') == True: # schema['type'] = { # 'type': 'array', # 'items': { # 'type': 'enum', # 'symbols': list(self.args['choices']) # }, # } # else: # schema['type'] = ['null', { # 'type': 'array', # 'items': { # 'type': 'enum', # 'symbols': list(self.args['choices']) # }, # }] schema['type'] = f"string{'' if self.args.get('required') == True else '?'}" return schema
[docs] def to_cwl_value(self): return '\n'.join(self.raw_value)
[docs] def to_click(self): args, kwargs = super().to_click() # kwargs['multiple'] = True import click kwargs['type'] = click.STRING return args, kwargs