def _gen(compact: bool): yield parser.metadata.id yield yield from self.text_block(parser.metadata.info.description) if (parser.metadata.external_docs is not None): yield " - External Documentation:" with self.indent(): yield parser.metadata.external_docs.url yield from self.text_block( parser.metadata.external_docs.description) if (parser.metadata.info.licence is not None): yield f" - License: {parser.metadata.info.licence.name}" with self.indent(): yield from Option(parser.metadata.info.licence.url).map( '({})'.format) if (parser.metadata.info.contact is not None): yield " - Contacts:" with self.indent(): yield from Option(parser.metadata.info.contact.name).map( ' - Name: {}'.format) yield from Option(parser.metadata.info.contact.url).map( ' - URL: {}'.format) yield from Option(parser.metadata.info.contact.email).map( ' - Email: {}'.format) yield yield f"Generated by Python OpenAPI Parser v{openapi_parser.__version__}"
class StringFilter(FilterImpl[AnyStr], Generic[AnyStr]): max_length: Optional[int] = None min_length: Optional[int] = None pattern: Optional[Pattern[AnyStr]] = field( default=None, metadata=config( decoder=lambda s: Option(s).map(re.compile).as_optional, encoder=lambda x: Option(x).map(lambda r: r.pattern).get_or_else( None))) def check_value(self, value: AnyStr) -> bool: return \ (self.max_length is None or self.max_length >= len(value)) and \ (self.min_length is None or self.min_length <= len(value)) and \ (self.pattern is None or self.pattern.search(value)) def mix_with(self, f: Filter[T]) -> Filter[T]: if (isinstance(f, StringFilter)): return StringFilter \ ( max_length = mix_options(self.max_length, f.max_length).map(min).as_optional, min_length = mix_options(self.min_length, f.min_length).map(max).as_optional, pattern = mix_options(self.pattern, f.pattern).map(combine_regular_expressions).as_optional, ) else: return super().mix_with(f)
def extra_gen(): params = method.all_parameters if (params): yield "Arguments:" with self.indent(): for p in params: p_name, p_cls, p_value, _ = self.parse_attribute( p.name, p.schema, is_required=p.required) yield f'{p_name}' + ':' + p_cls.map( ' `{}`'.format).get_or_else('') + p_value.map( ', default: `{}`'.format).get_or_else('') + '.' with self.indent(): yield from self.text_block( p_value.map(lambda _: 'Optional.').get_or_else( '**REQUIRED.**') + ' ' + Option(p.description).get_or_else('')) yield if (method.request_body is not None): media_type, media_data = method.regular_request_parser p_name, p_cls, p_value, _ = self.parse_attribute( 'data', media_data.schema, is_required=True) yield f'{p_name}' + ':' + p_cls.map( ' `{}`'.format).get_or_else('') + '.' with self.indent(): yield f"**REQUIRED.** Request body" + ( " of '{media_type}' media-type" if media_data != '*/*' else '' ) + Option(media_data).flat_map( lambda m: Option(m.encoding)).map( " (encoding: '{}')".format).get_or_else('') if (media_data is not None and media_data.schema is not None): yield from self.text_block( media_data.schema.summary, compact=True) yield from self.text_block( media_data.schema.description, compact=True) yield _, resp = method.regular_response if (resp is not None): _, media_data = resp.regular_request_parser if (media_data is not None and media_data.schema is not None): yield "Returns:" with self.indent(): _, r_cls, _, _ = self.parse_attribute( 'response', media_data.schema, is_required=True) yield from self.text_block( r_cls.map('`{}`. '.format).get_or_else('') + Option(resp.description).get_or_else(''), compact=True) yield from self.text_block(media_data.schema.summary, compact=True) yield from self.text_block( media_data.schema.description, compact=True) yield
def decoder(self): if (self.discriminator is None): return None items = Option(self.any_of).get_or_else(list()) + Option( self.one_of).get_or_else(list()) + Option(self.all_of).get_or_else( list()) for it in items: if (it.cls != dict and not isinstance(it.cls, ModelClassImpl)): raise InvalidAlternativeTypes(self, it.cls) return self.discriminator.decoder(items)
def decoder(self, items: List[ModelSchema]) -> Optional[str]: mapping = Option(self.mapping).get_or_else( {get_class_name(it.cls): get_class_name(it.cls) for it in items}) if (len(mapping) < 2): return None return f"discriminator_decoder(discriminator_key={self.property_name!r}, mappings={{ {', '.join(f'{k!r}: {v}' for k, v in mapping.items())} }})"
def _mix_options(options: Iterable[Opt]) -> Iterator[T]: for op in options: if (not Option.is_option(op)): op = Option(op) yield from op
def load_schema(self, schema_data: Dict[str, Any], path: str, *, is_top_level: bool, force_name: Optional[str] = None, **kwargs) -> ModelSchema: if (force_name is not None and not is_top_level): name = force_name else: _, _, name = split_path_right(path) field_data = ModelSchemaImpl.from_dict(schema_data) field_data.property_name = name inheritance_data = InheritanceFilter.from_dict(schema_data) if (not inheritance_data.is_empty): inheritance_data.all_of = self._load_fields( inheritance_data.all_of, path + '/allOf') inheritance_data.any_of = self._load_fields( inheritance_data.any_of, path + '/anyOf') inheritance_data.one_of = self._load_fields( inheritance_data.one_of, path + '/oneOf') if (inheritance_data.filter_not is not None): # noinspection PyTypeChecker inheritance_data.filter_not = self.load_schema( inheritance_data.filter_not, path + '/not') if (inheritance_data.discriminator is not None): if (field_data.property_type is None): field_data.property_type = PropertyType.Object elif (field_data.property_type != PropertyType.Object): # ToDo: Discriminator fields could not be used in combination with non-object properties raise ValueError( "Discriminator fields could not be used in combination with non-object properties" ) if (field_data.property_type is None): field_data.cls = Any elif (field_data.property_type == PropertyType.Integer): field_data.cls = int field_data.filter = NumericFilter.from_dict(schema_data) elif (field_data.property_type == PropertyType.Number): field_data.cls = float field_data.filter = NumericFilter.from_dict(schema_data) elif (field_data.property_type == PropertyType.String): if (DateFormatName.contains_value(field_data.property_format)): field_data.cls = datetime field_data.filter = DateFilter.from_dict(schema_data) else: if (field_data.property_format in ('byte', 'binary')): field_data.cls = bytes else: field_data.cls = str field_data.filter = StringFilter.from_dict(schema_data) elif (field_data.property_type == PropertyType.Boolean): field_data.cls = bool elif (field_data.property_type == PropertyType.Array): if ('items' in schema_data): items = self.load_schema(schema_data['items'], path + '/items', force_name=field_data.property_name + self.id_separator + 'item') field_data.cls = ListProxy[items.cls] else: field_data.cls = list field_data.filter = ArrayFilter.from_dict(schema_data) elif (field_data.property_type == PropertyType.Object): additional_properties: Union[bool, Dict[str, Any]] = schema_data.get( 'additionalProperties', True) if ('properties' in schema_data): field_data.cls = self.load_class( schema_data, path, is_top_level=is_top_level, force_name=field_data.property_name) elif (additional_properties == False): raise InvalidSchemaFields( path, "'additionalProperties=False' is not allowed in combination with missing 'properties' for 'object' invalid_type" ) elif (isinstance(additional_properties, dict)): cls = self.load_schema(additional_properties, path + '/additionalProperties', force_name=field_data.property_name + self.id_separator + 'item') field_data.cls = DictProxy[str, cls] field_data.filter = DictFilter.from_dict(schema_data) else: field_data.cls = dict field_data.filter = DictFilter.from_dict(schema_data) field_data.filter = EmptyFilter().mix_with( field_data.filter).mix_with(inheritance_data) if (inheritance_data.any_of is not None or inheritance_data.one_of is not None): if (inheritance_data.all_of is not None): raise InvalidSchemaFields( path, f"allOf is not allowed in combination with oneOf/anyOf") items = Option(inheritance_data.any_of).get_or_else( list()) + Option(inheritance_data.one_of).get_or_else(list()) field_data.cls = UnionProxy[tuple(items)] if (inheritance_data.discriminator is not None): field_data.cls = field_data.cls.with_discriminator( inheritance_data.discriminator) elif (inheritance_data.all_of is not None and field_data.cls == Any): field_data.cls, inh_filter = self._merge_classes( inheritance_data.all_of, path, is_top_level=is_top_level, force_name=field_data.property_name) inheritance_data = inheritance_data.mix_with(inh_filter) field_data.filter = field_data.filter.mix_with(inheritance_data) if ('enum' in schema_data): enum_data = ModelEnumDataImpl.from_dict(schema_data) enum_data.name = field_data.property_name enum_data.base_class = field_data.cls enum_data.path = path + '/enum' enum_data.pretty_path = None field_data.cls = enum_data return field_data
def _name_gen(s: ModelServer) -> Option[str]: return Option(s.description or s.url).map( self.enum_entry_name_pretty).map(self.object_valid_name_filter)