class LogGame(types.Type): season: int = validators.Number( 1, 11, description="Overwatch season from 1 to 11.") sr: int = validators.Number( 0, 5000, description="You SR at the end of the game from 0 to 5000.") map: str = validators.String( enum=MAP_CHOICES, allow_null=True, description=f"Name of the map the game was played.", ) heroes: List[str] = validators.Array( items=validators.String(enum=HERO_CHOICES), unique_items=True, allow_null=True, description=f"List of heroes name that you played for that game.", ) comment: str = validators.String( allow_null=True, description="Free text field to leave a comment for that game.") thrower_team: bool = validators.Boolean( allow_null=True, description="If there was a thrower in your team.") thrower_enemy_team: bool = validators.Boolean( allow_null=True, description="If there was a thrower in the enemy team.") leaver_team: bool = validators.Boolean( allow_null=True, description="If there was a leaver on your team.") leaver_enemy_team: bool = validators.Boolean( allow_null=True, description="If there was a leaver on the enemy team.") group_with: List[str] = validators.Array( items=validators.String(), allow_null=True, unique_items=True, description="List of people of you grouped with for this game.", )
class GameType(types.Type): name = validators.String() platform = validators.String() score = validators.Number() resolution_tested = validators.String(pattern="^\d+x\d+$") genre = validators.Array() players = validators.Array() language = validators.Number() awesome_city = CityType
class UserType(types.Type): _id = validators.String(allow_null=True) username = validators.String(min_length=3, max_length=30) email = validators.String(allow_null=True, pattern=EMAIL_REGEX) names = validators.Array(items=validators.String(), allow_null=True) lastnames = validators.Array(items=validators.String(), allow_null=True) groups = validators.Array(unique_items=True, items=validators.String(enum=['admin', 'developer', 'basic']))
class GetResponse(types.Type): """ default type for get request responses """ count = validators.Integer(description="The number of objects matching this query.", allow_null=True) next = validators.String(description="The url for the next page of data.", allow_null=True) previous = validators.String(description="The url for the previous page of data.", allow_null=True) results = validators.Array(description="The list of objects returned by the query.", allow_null=True)
def coerce_generics(self, annotation): origin = getattr(annotation, '__origin__', annotation) if (isinstance(origin, type) and issubclass(origin, typing.List) and getattr(annotation, '__args__', None) and issubclass(annotation.__args__[0], types.Type)): return validators.Array(items=annotation.__args__[0]) return annotation
class DescriptionEvent(BaseBlock): BLOCK_TYPE = "event_description" description = validators.String(allow_null=True) free_text = validators.String(allow_null=True) price = validators.String(allow_null=True) tags = validators.Array(allow_null=True) @classmethod def from_es(cls, es_poi, lang): if es_poi.PLACE_TYPE != 'event': return None description = es_poi.get('description') free_text = es_poi.get('free_text') price = es_poi.get('pricing_info') tags = es_poi.get('tags', []) if isinstance(tags, str): tags = tags.split(';') if not description: return None return cls( description=description, free_text=free_text, price=price, tags=tags )
class CuisineBlock(BaseBlock): BLOCK_TYPE = "cuisine" SUPPORTED_DIETS = ("vegetarian", "vegan", "gluten_free") STATUS_YES = "yes" STATUS_NO = "no" STATUS_ONLY = "only" STATUS_UNKNOWN = "unknown" cuisines = validators.Array(items=Cuisine) vegetarian = validators.String() vegan = validators.String() gluten_free = validators.String() @classmethod def from_es(cls, es_poi, lang): cuisine = es_poi.get("properties", {}).get("cuisine") vegetarian = get_diet_status("vegetarian", es_poi) vegan = get_diet_status("vegan", es_poi) gluten_free = get_diet_status("gluten_free", es_poi) cuisines = [] if cuisine is not None: cuisines = [Cuisine(name=b) for b in cuisine.split(";")] elif (vegetarian == cls.STATUS_UNKNOWN and vegan == cls.STATUS_UNKNOWN and gluten_free == cls.STATUS_UNKNOWN): return None return cls(cuisines=cuisines, vegetarian=vegetarian, vegan=vegan, gluten_free=gluten_free)
class BaseExtractionJSONParams(CoercingType): """Common extraction parameters validator""" domains = validators.Array( items=DomainValidator(enum=list(TAG_DOMAINS.keys())), unique_items=True, description= 'List of domains to search, if not provided ALL domains will be included', allow_null=True, ) offset = validators.Integer(minimum=0, allow_null=True, description='The paging offset') limit = validators.Integer( minimum=1, maximum=10000, default=10, allow_null=True, description='The paging limit.', ) min_score = validators.Number( minimum=0.1, allow_null=True, description= 'The minimum search score required. No default is applied when not provided. ' 'Ignored when `constant_score` is on.', ) constant_score = validators.Boolean( default=True, allow_null=False, description= 'Disables relevance scoring when `True`. All results will have score `1`.', )
def coerce_generics(self, annotation): if ( isinstance(annotation, type) and issubclass(annotation, typing.List) and annotation.__args__ and issubclass(annotation.__args__[0], types.Type) ): return validators.Array(items=annotation.__args__[0]) return annotation
class Basket(types.Type): """Represent the item that was added to a basket.""" id = validators.String(max_length=48, allow_null=True) products = validators.Array(items=Product, allow_null=True) @classmethod def from_model(cls, obj): return cls(id=str(obj.id), products=[Product.from_model(p) for p in obj.products])
def create_get_response_class(self, model_name, response_object_class=validators.Object): return type( model_name, # name of the class # (eval('types.Type'),), # super class as tuple (self.get_response_class,), # super classes at a tuple { 'results': validators.Array(allow_null=True, items=response_object_class) } )
class Anime(types.Type): id = validators.Integer(allow_null=True) title = validators.String(max_length=2500) year = validators.Integer(minimum=1900, maximum=2050) episodes = validators.Integer(maximum=9999) status = validators.String(enum=list(ANIME_VALID_STATUS)) type = validators.String(allow_null=True) animeSeason = validators.Object(allow_null=True) picture = validators.String(allow_null=True) sources = validators.Array(allow_null=True)
class Movie(types.Type): id = validators.Integer(allow_null=True) # assign in POST genre = validators.Array(items=validators.String(enum=list(VALID_GENRES))) director_name = validators.String(max_length=100) year = validators.Integer(minimum=1900, maximum=2050) language = validators.String(max_length=100, enum=list(VALID_LANGUAGES), allow_null=True) title = validators.String(max_length=200) rating = validators.Number(minimum=0, maximum=10)
class CsrfSettings(types.Type): CSRF_COOKIE_NAME = validators.String(default='csrftoken') CSRF_COOKIE_AGE = validators.Integer(default=60 * 60 * 24 * 7 * 52) CSRF_COOKIE_DOMAIN = validators.String(allow_null=True) CSRF_COOKIE_PATH = validators.String(default='/') CSRF_COOKIE_SECURE = validators.Boolean(default=False) CSRF_COOKIE_HTTPONLY = validators.Boolean(default=False) CSRF_HEADER_NAME = validators.String(default='HTTP_X_CSRFTOKEN') CSRF_TOKEN_FIELD_NAME = validators.String(default='csrf_token') CSRF_TRUSTED_ORIGINS = validators.Array(default=[])
class Block(PickleType): height = validators.Integer() timestamp = validators.DateTime() txns = validators.Array(items=Transaction, allow_null=True, default=[]) mined_hash = validators.String(max_length=100) previous_hash = validators.String(max_length=100, allow_null=True) nonce = validators.Integer() @property def previous_block(self): return get_block(self.previous_hash)
class FeatureUpdate(types.Type): version = validators.String(description="The feature number version.") enabled = validators.Boolean() deny = validators.Boolean() services = validators.Array( unique_items=True, items=validators.Integer(), allow_null=True, description="Array with services allowed to access the feature.", )
class AuthenticatedUserData(types.Type): id = validators.Integer() email = validators.String(description="Email address", pattern="[^@]+@[^@]+\.[^@]+", allow_null=True) phone = validators.String(description="Phone number", pattern="\D*", allow_null=True) first_name = validators.String() last_name = validators.String() language = validators.Integer() groups = validators.Array() location = validators.Integer() picture = validators.String(allow_null=True)
class BreweryBlock(BaseBlock): BLOCK_TYPE = "brewery" beers = validators.Array(items=Beer) @classmethod def from_es(cls, es_poi, lang): brewery = es_poi.get("properties", {}).get("brewery") if brewery is None: return None beers = [Beer(name=b) for b in brewery.split(";")] return cls(beers=beers)
class HappyHourBlock(BaseBlock): BLOCK_TYPE = 'happy_hours' STATUSES = ['yes', 'no'] status = validators.String(enum=STATUSES) next_transition_datetime = validators.String(allow_null=True) seconds_before_next_transition = validators.Integer(allow_null=True) raw = validators.String() days = validators.Array(items=DaysType) @classmethod def init_class(cls, status, next_transition_datetime, time_before_next, oh, poi_dt, raw): return cls( status=status, next_transition_datetime=next_transition_datetime, seconds_before_next_transition=time_before_next, raw=oh.field, days=get_days(cls, oh, poi_dt) ) @classmethod def from_es(cls, es_poi, lang): return parse_time_block(cls, es_poi, lang, es_poi.get_raw_happy_hours())
class OpeningHourBlock(BaseBlock): BLOCK_TYPE = 'opening_hours' STATUSES = ['open', 'closed'] status = validators.String(enum=STATUSES) next_transition_datetime = validators.String(allow_null=True) seconds_before_next_transition = validators.Integer(allow_null=True) is_24_7 = validators.Boolean() raw = validators.String() days = validators.Array(items=DaysType) @classmethod def init_class(cls, status, next_transition_datetime, time_before_next, oh, poi_dt, raw): if raw == '24/7' or oh.is_24_7: return cls(status=status, next_transition_datetime=None, seconds_before_next_transition=None, is_24_7=True, raw=oh.field, days=get_days(cls, oh, poi_dt)) if all(r.status == 'closed' for r in oh.rules): # Ignore opening_hours such as "Apr 1-Sep 30: off", causing overflow return None return cls(status=status, next_transition_datetime=next_transition_datetime, seconds_before_next_transition=time_before_next, is_24_7=oh.is_24_7, raw=oh.field, days=get_days(cls, oh, poi_dt)) @classmethod def from_es(cls, es_poi, lang): return parse_time_block(cls, es_poi, lang, es_poi.get_raw_opening_hours())
class OpeningDayEvent(BaseBlock): BLOCK_TYPE = "event_opening_dates" date_start = validators.DateTime() date_end = validators.DateTime() space_time_info = validators.String(allow_null=True) timetable = validators.Array(items=TimeTableItem) @classmethod def from_es(cls, es_poi, lang): if es_poi.PLACE_TYPE != 'event': return None date_start = es_poi.get('date_start') date_end = es_poi.get('date_end') space_time_info= es_poi.get('space_time_info') timetable = es_poi.get('timetable') or '' if not date_start or not date_end: return None timetable = timetable.split(';') new_format_timetable = [] for tt in filter(None, timetable): date_start_end = tt.split(' ') new_format_timetable.append( TimeTableItem(beginning=date_start_end[0], end=date_start_end[1]) ) timetable = new_format_timetable return cls( date_start=date_start, date_end=date_end, space_time_info=space_time_info, timetable=timetable )
def load_type(typename, struct, allow_null): attrs = {'allow_null': True} if allow_null else {} if typename == 'string': if 'minLength' in struct: attrs['min_length'] = struct['minLength'] if 'maxLength' in struct: attrs['max_length'] = struct['maxLength'] if 'pattern' in struct: attrs['pattern'] = struct['pattern'] if 'format' in struct: attrs['format'] = struct['format'] return validators.String(**attrs) if typename in ['number', 'integer']: if 'minimum' in struct: attrs['minimum'] = struct['minimum'] if 'maximum' in struct: attrs['maximum'] = struct['maximum'] if 'exclusiveMinimum' in struct: attrs['exclusive_minimum'] = struct['exclusiveMinimum'] if 'exclusiveMaximum' in struct: attrs['exclusive_maximum'] = struct['exclusiveMaximum'] if 'multipleOf' in struct: attrs['multiple_of'] = struct['multipleOf'] if 'format' in struct: attrs['format'] = struct['format'] if typename == 'integer': return validators.Integer(**attrs) return validators.Number(**attrs) if typename == 'boolean': return validators.Boolean(**attrs) if typename == 'object': if 'properties' in struct: attrs['properties'] = dict_type([ (key, decode(value)) for key, value in struct['properties'].items() ]) if 'required' in struct: attrs['required'] = struct['required'] if 'minProperties' in struct: attrs['min_properties'] = struct['minProperties'] if 'maxProperties' in struct: attrs['max_properties'] = struct['maxProperties'] if 'required' in struct: attrs['required'] = struct['required'] if 'patternProperties' in struct: attrs['pattern_properties'] = dict_type([ (key, decode(value)) for key, value in struct['patternProperties'].items() ]) if 'additionalProperties' in struct: if isinstance(struct['additionalProperties'], bool): attrs['additional_properties'] = struct['additionalProperties'] else: attrs['additional_properties'] = decode( struct['additionalProperties']) return validators.Object(**attrs) if typename == 'array': if 'items' in struct: if isinstance(struct['items'], list): attrs['items'] = [decode(item) for item in struct['items']] else: attrs['items'] = decode(struct['items']) if 'additionalItems' in struct: if isinstance(struct['additionalItems'], bool): attrs['additional_items'] = struct['additionalItems'] else: attrs['additional_items'] = decode(struct['additionalItems']) if 'minItems' in struct: attrs['min_items'] = struct['minItems'] if 'maxItems' in struct: attrs['max_items'] = struct['maxItems'] if 'uniqueItems' in struct: attrs['unique_items'] = struct['uniqueItems'] return validators.Array(**attrs) assert False
class DaysType(types.Type): dayofweek = validators.Integer(minimum=1, maximum=7) local_date = validators.Date() status = validators.String(enum=['open', 'closed']) opening_hours = validators.Array(items=OpeningHoursType)
import json from apistar import types, validators from apistar.codecs.base import BaseCodec from apistar.compat import dict_type from apistar.exceptions import ParseError JSON_SCHEMA = validators.Object( def_name='JSONSchema', properties=[ ('$ref', validators.String()), ('type', validators.String() | validators.Array(items=validators.String())), ('enum', validators.Array(unique_items=True, min_items=1)), ('definitions', validators.Object( additional_properties=validators.Ref('JSONSchema'))), # String ('minLength', validators.Integer(minimum=0)), ('maxLength', validators.Integer(minimum=0)), ('pattern', validators.String(format='regex')), ('format', validators.String()), # Numeric ('minimum', validators.Number()), ('maximum', validators.Number()), ('exclusiveMinimum', validators.Boolean()), ('exclusiveMaximum', validators.Boolean()), ('multipleOf', validators.Number(minimum=0.0, exclusive_minimum=True)),
class OpeningHourBlock(BaseBlock): BLOCK_TYPE = 'opening_hours' status = validators.String(enum=['open', 'closed']) next_transition_datetime = validators.String(allow_null=True) seconds_before_next_transition = validators.Integer(allow_null=True) is_24_7 = validators.Boolean() raw = validators.String() days = validators.Array(items=DaysType) @classmethod def from_es(cls, es_poi, lang): raw = es_poi.get('properties', {}).get('opening_hours') if raw is None: return None poi_coord = get_coord(es_poi) poi_lat = poi_coord[0] poi_lon = poi_coord[1] is247 = raw == '24/7' poi_tzname = tz.tzNameAt(poi_lat, poi_lon, forceTZ=True) poi_tz = get_tz(poi_tzname, poi_lat, poi_lon) poi_location = (poi_lat, poi_lon, poi_tzname, 24) if poi_tz is None: logger.info("No timezone found for poi %s", es_poi.get('id')) return None try: oh = hoh.OHParser(raw, location=poi_location) except HOHError: logger.info("Failed to parse OSM opening_hour field", exc_info=True) return None poi_dt = UTC.localize(datetime.utcnow()).astimezone(poi_tz) if oh.is_open(poi_dt.replace(tzinfo=None)): status = 'open' else: status = 'closed' if is247: return cls(status=status, next_transition_datetime=None, seconds_before_next_transition=None, is_24_7=is247, raw=oh.field, days=cls.get_days(oh, dt=poi_dt)) # The current version of the hoh lib doesn't allow to use the next_change() function # with an offset aware datetime. # This is why we replace the timezone info until this problem is fixed in the library. try: nt = oh.next_change(dt=poi_dt.replace(tzinfo=None)) except HOHError: logger.info( "HOHError: Failed to compute next transition for poi %s", es_poi.get('id'), exc_info=True) return None # Then we localize the next_change transition datetime in the local POI timezone. next_transition = poi_tz.localize(nt.replace(tzinfo=None)) next_transition = cls.round_dt_to_minute(next_transition) next_transition_datetime = next_transition.isoformat() delta = next_transition - poi_dt time_before_next = int(delta.total_seconds()) return cls(status=status, next_transition_datetime=next_transition_datetime, seconds_before_next_transition=time_before_next, is_24_7=is247, raw=oh.field, days=cls.get_days(oh, dt=poi_dt)) @staticmethod def round_dt_to_minute(dt): dt += timedelta(seconds=30) return dt.replace(second=0, microsecond=0) @staticmethod def round_time_to_minute(t): dt = datetime.combine(date(2000, 1, 1), t) rounded = OpeningHourBlock.round_dt_to_minute(dt) return rounded.time() @classmethod def get_days(cls, oh_parser, dt): last_monday = dt.date() - timedelta(days=dt.weekday()) days = [] for x in range(0, 7): day = last_monday + timedelta(days=x) oh_day = oh_parser.get_day(day) periods = oh_day.opening_periods() day_value = { 'dayofweek': day.isoweekday(), 'local_date': day.isoformat(), 'status': 'open' if len(periods) > 0 else 'closed', 'opening_hours': [] } for beginning_dt, end_dt in periods: if beginning_dt.date() < day: continue beginning = cls.round_time_to_minute(beginning_dt.time()) end = cls.round_time_to_minute(end_dt.time()) day_value['opening_hours'].append({ 'beginning': beginning.strftime('%H:%M'), 'end': end.strftime('%H:%M') }) days.append(day_value) return days
from apistar.compat import dict_type from apistar.document import Document, Field, Link, Section from apistar.exceptions import ParseError SCHEMA_REF = validators.Object( properties={'$ref': validators.String(pattern='^#/components/schemas/')}) RESPONSE_REF = validators.Object( properties={'$ref': validators.String(pattern='^#/components/responses/')}) OPEN_API = validators.Object( def_name='OpenAPI', title='OpenAPI', properties=[ ('openapi', validators.String()), ('info', validators.Ref('Info')), ('servers', validators.Array(items=validators.Ref('Server'))), ('paths', validators.Ref('Paths')), ('components', validators.Ref('Components')), ('security', validators.Ref('SecurityRequirement')), ('tags', validators.Array(items=validators.Ref('Tag'))), ('externalDocs', validators.Ref('ExternalDocumentation')), ], pattern_properties={ '^x-': validators.Any(), }, additional_properties=False, required=['openapi', 'info', 'paths'], definitions={ 'Info': validators.Object(properties=[ ('title', validators.String()),
properties={'$ref': validators.String(pattern='^#/components/schemas/')} ) RESPONSE_REF = validators.Object( properties={'$ref': validators.String(pattern='^#/components/responses/')} ) SWAGGER = validators.Object( def_name='Swagger', title='Swagger', properties=[ ('swagger', validators.String()), ('info', validators.Ref('Info')), ('paths', validators.Ref('Paths')), ('host', validators.String()), ('basePath', validators.String()), ('schemes', validators.Array(items=validators.String())), ('consumes', validators.Array(items=validators.String())), ('produces', validators.Array(items=validators.String())), ('definitions', validators.Object(additional_properties=validators.Any())), ('parameters', validators.Object(additional_properties=validators.Ref('Parameters'))), ('responses', validators.Object(additional_properties=validators.Ref('Responses'))), ('securityDefinitions', validators.Object(additional_properties=validators.Ref('SecurityScheme'))), ('security', validators.Ref('SecurityRequirement')), ('tags', validators.Array(items=validators.Ref('Tag'))), ('externalDocs', validators.Ref('ExternalDocumentation')), ], pattern_properties={ '^x-': validators.Any(), }, additional_properties=False, required=['swagger', 'info', 'paths'],
import json from apistar import types, validators from apistar.codecs.base import BaseCodec from apistar.compat import dict_type from apistar.exceptions import ParseError JSON_SCHEMA = validators.Object( def_name="JSONSchema", properties=[ ("$ref", validators.String()), ("type", validators.String() | validators.Array(items=validators.String())), ("enum", validators.Array(unique_items=True, min_items=1)), ( "definitions", validators.Object(additional_properties=validators.Ref("JSONSchema")), ), # String ("minLength", validators.Integer(minimum=0)), ("maxLength", validators.Integer(minimum=0)), ("pattern", validators.String(format="regex")), ("format", validators.String()), # Numeric ("minimum", validators.Number()), ("maximum", validators.Number()), ("exclusiveMinimum", validators.Boolean()), ("exclusiveMaximum", validators.Boolean()), ("multipleOf", validators.Number(minimum=0.0, exclusive_minimum=True)), # Object ( "properties",
SCHEMA_REF = validators.Object( properties={'$ref': validators.String(pattern='^#/components/schemas/')}) RESPONSE_REF = validators.Object( properties={'$ref': validators.String(pattern='^#/components/responses/')}) SWAGGER = validators.Object( def_name='Swagger', title='Swagger', properties=[ ('swagger', validators.String()), ('info', validators.Ref('Info')), ('paths', validators.Ref('Paths')), ('host', validators.String()), ('basePath', validators.String()), ('schemes', validators.Array(items=validators.String())), ('consumes', validators.Array(items=validators.String())), ('produces', validators.Array(items=validators.String())), ('definitions', validators.Object(additional_properties=validators.Any())), ('parameters', validators.Object( additional_properties=validators.Ref('Parameters'))), ('responses', validators.Object(additional_properties=validators.Ref('Responses'))), ('securityDefinitions', validators.Object( additional_properties=validators.Ref('SecurityScheme'))), ('security', validators.Array(items=validators.Ref('SecurityRequirement'))), ('tags', validators.Array(items=validators.Ref('Tag'))),
def load_type(typename, struct, allow_null): attrs = {"allow_null": True} if allow_null else {} if typename == "string": if "minLength" in struct: attrs["min_length"] = struct["minLength"] if "maxLength" in struct: attrs["max_length"] = struct["maxLength"] if "pattern" in struct: attrs["pattern"] = struct["pattern"] if "format" in struct: attrs["format"] = struct["format"] return validators.String(**attrs) if typename in ["number", "integer"]: if "minimum" in struct: attrs["minimum"] = struct["minimum"] if "maximum" in struct: attrs["maximum"] = struct["maximum"] if "exclusiveMinimum" in struct: attrs["exclusive_minimum"] = struct["exclusiveMinimum"] if "exclusiveMaximum" in struct: attrs["exclusive_maximum"] = struct["exclusiveMaximum"] if "multipleOf" in struct: attrs["multiple_of"] = struct["multipleOf"] if "format" in struct: attrs["format"] = struct["format"] if typename == "integer": return validators.Integer(**attrs) return validators.Number(**attrs) if typename == "boolean": return validators.Boolean(**attrs) if typename == "object": if "properties" in struct: attrs["properties"] = dict_type( [(key, decode(value)) for key, value in struct["properties"].items()] ) if "required" in struct: attrs["required"] = struct["required"] if "minProperties" in struct: attrs["min_properties"] = struct["minProperties"] if "maxProperties" in struct: attrs["max_properties"] = struct["maxProperties"] if "required" in struct: attrs["required"] = struct["required"] if "patternProperties" in struct: attrs["pattern_properties"] = dict_type( [ (key, decode(value)) for key, value in struct["patternProperties"].items() ] ) if "additionalProperties" in struct: if isinstance(struct["additionalProperties"], bool): attrs["additional_properties"] = struct["additionalProperties"] else: attrs["additional_properties"] = decode(struct["additionalProperties"]) return validators.Object(**attrs) if typename == "array": if "items" in struct: if isinstance(struct["items"], list): attrs["items"] = [decode(item) for item in struct["items"]] else: attrs["items"] = decode(struct["items"]) if "additionalItems" in struct: if isinstance(struct["additionalItems"], bool): attrs["additional_items"] = struct["additionalItems"] else: attrs["additional_items"] = decode(struct["additionalItems"]) if "minItems" in struct: attrs["min_items"] = struct["minItems"] if "maxItems" in struct: attrs["max_items"] = struct["maxItems"] if "uniqueItems" in struct: attrs["unique_items"] = struct["uniqueItems"] return validators.Array(**attrs) assert False