def get_performer_available_time(curr_id): v = Validator(purge_unknown=True) schema = { 'service_id': { 'required': True, 'coerce': int }, 'coordx': { 'required': True, 'coerce': float }, 'coordy': { 'required': True, 'coerce': float }, 'date': { 'required': True, 'coerce': lambda x: parse(x).date() } } req_data = v.validated(request.args.to_dict(), schema) if not req_data: abort(400, v.errors) return jsonify([[str(x[0]), str(x[1])] for x in calc_vacant_hours(perf_id=curr_id, serv_id=req_data['service_id'], coord=(req_data['coordx'], req_data['coordy']), xdate=req_data['date'])]), 200
def linode_action_input_validated(schema, definition, args): from cerberus import Validator from json import dumps log.vvvvv('linode_action_input_validated(%s): %s' % (definition, str(args))) v = Validator( schema=schema.get(definition), purge_unknown=True, ) normalized = v.normalized(args) log.vvvvv('linode_action_input_validated(%s): normalized %s' % (definition, str(normalized))) if not v.validate(normalized): for err in dumps(v.errors, indent=2).split("\n"): log.warning('linode_action_input_validated(%s): %s' % (definition, err)) raise AnsibleError('while validating %s got errors: %s' % (definition, str(v.errors))) validated = v.validated(args) log.vvv('linode_action_input_validated(%s): validated %s' % (definition, str(validated))) return validated
def business_schedule_get(): v = Validator(purge_unknown=True) schema = { 'service_id': { 'default': None, 'coerce': lambda x: int(x) if x else x, 'nullable': True }, 'performer_id': { 'default': None, 'coerce': lambda x: int(x) if x else x, 'nullable': True }, 'date': { 'default': None, 'coerce': lambda x: parse(x) if x else x, 'nullable': True } } req_data = v.validated(request.args.to_dict(), schema) if not req_data: abort(400, v.errors) business = db.session.query(Business).filter( Business.user_id == get_jwt_claims()['id']).first() perf_id = req_data['performer_id'] if perf_id and Performer.get(perf_id).business_id != business.id: abort(403) serv_id = req_data['service_id'] if serv_id and Service.get(serv_id).business_id != business.id: abort(403) return jsonify(get_schedule(business_id=business.id, kwargs=req_data)), 200
def register(): v = Validator(purge_unknown=True) schema = { 'email': { 'type': 'string', 'required': True # 'regex': REGEX_EMAIL }, 'password': { 'required': True, 'type': 'string' }, 'role': { 'type': 'string', 'required': True, 'allowed': ['user', 'business'] } } req_data = v.validated(request.get_json(), schema) if not req_data: abort(400, v.errors) user = db.session.query(User).filter( User.email == req_data['email']).first() if user: return jsonify({"msg": "User already exists"}), 422 user = User(email=req_data['email'], role=req_data['role']) db.session.add(user) user.set_password(req_data['password']) db.session.commit() return jsonify({"msg": "Mr Bee flies around"}), 200
def create_business(): v = Validator(purge_unknown=True) schema = { 'name': { 'type': 'string', 'required': True }, 'phone': { 'type': 'string', 'required': True # 'regex': REGEX_PHONE }, 'address': { 'type': 'string' } } req_data = v.validated(request.get_json(), schema) if not req_data: abort(400, v.errors) business = db.session.query(Business).filter( Business.name == req_data['name']).first() if business: return jsonify({"msg": "Business already exists"}), 400 business = Business(user_id=get_jwt_claims()['id']) return add(business, req_data)
def post(self): us = ServiceLocator.resolve(ServiceLocator.USERS) v = Validator(check_params_schema) args = v.validated(request.get_json()) if args is None: return ApiResponse(status=4001, errors=v.errors) try: login = args.get('login', None) email = args.get('email', None) login_result = login and us.check_login(login) email_result = email and us.check_email(email) return { 'login': login_result, 'email': email_result } except Exception as ex: error(u'UsersCheckAPI.post', ex) return { 'login': None, 'email': None }
def post(self): us = ServiceLocator.resolve(ServiceLocator.USERS) ss = ServiceLocator.resolve(ServiceLocator.SESSIONS) v = Validator(user_signin_schema) args = v.validated(request.get_json()) if args is None: return ApiResponse(status=4001, errors=v.errors) login = args.get(u'login') password = args.get(u'password') user = us.sign_in(login, password) if user is None: return ApiResponse(status=4001, errors=errors.SignErrors.login_or_password_wrong(['login', 'password'])) token = us.make_auth_token(user) # Save the user to session ss.create(user, token) user[u'auth_token'] = token return user
def validate(self, config_dict): """Validates the mode using its relevant configuration dict Returns a validated configuration dict with the mode filled in. If no mode is given in the input dict, a default mode will be filled in if availble. If the mode has a validation_schema, it will be used to validate the input dict. If any error is encountered during the process, A serializer ValidationError will be raised with the error. Args: config_dict (dict): A dictionary of input structure that this mode is a part of Returns: dict: A version of the input dictionary with defaults filled in based on the validation_schema Raises: serializers.ValidationError: If validation fails """ mode_value = self._get_mode_from_config_dict(config_dict) if not mode_value: mode_value = self.get_default_mode() if not mode_value: return config_dict if not self.mode_exists(mode_value): return config_dict config_dict = self._set_mode_in_config_dict(mode_value, config_dict) mode = configdb.get_mode_with_code(self._instrument_type, mode_value, self._mode_type) validation_schema = mode.get('validation_schema', {}) validator = Validator(validation_schema) validator.allow_unknown = True validated_config_dict = validator.validated( config_dict) or config_dict.copy() if validator.errors: raise serializers.ValidationError( _(f'{self._mode_type.capitalize()} mode {mode_value} requirements are not met: {cerberus_validation_error_to_str(validator.errors)}' )) return validated_config_dict
def post(self): u""" Creates new card and adds it to group. :return: Card """ v = Validator(card_schema) args = v.validated(request.get_json()) if args is None: return ApiResponse(status=4001, errors=v.errors) foreign = args.get(u'foreign') native = args.get(u'native') group_id = args.get(u'group_id') transcription = args.get(u'transcription', u'') context = args.get(u'context', u'') user = self.ss.get_user() group = self.gs.single(group_id, user) exists_card = self.cs.exists(user, foreign, user.foreign_lng) if exists_card: return ApiResponse(status=409, errors=CardsErrors.card_already_exists(foreign, [u'foreign'])) card = self.cs.create(user, group, foreign, native, transcription, context) if card is None: return ApiResponse(status=500, errors=ServerErrors.internal_server_error([])) return card
def flexio_handler(flex): # get the input input = flex.input.read() input = json.loads(input) if not isinstance(input, list): input = [] # define the expected parameters and map the values to the parameter names # based on the positions of the keys/values params = OrderedDict() params['properties'] = {'required': False, 'validator': validator_list, 'coerce': to_list, 'default': '*'} params['filter'] = {'required': False, 'type': 'string', 'default': ''} # placeholder to match form of index-styled functions params['config'] = {'required': False, 'type': 'string', 'default': ''} # index-styled config string input = dict(zip(params.keys(), input)) # validate the mapped input against the validator v = Validator(params, allow_unknown = True) params = v.validated(input) if params is None: raise ValueError # get the properties to return and the property map; # if we have a wildcard, get all the properties properties = [p.lower().strip() for p in params['properties']] if len(properties) == 1 and (properties[0] == '' or properties[0] == '*'): properties = list(get_item_info({}).keys()) # get any configuration settings config = urllib.parse.parse_qs(params['config']) config = {k: v[0] for k, v in config.items()} limit = int(config.get('limit', 100)) if limit >= 1000: limit = 1000 headers = config.get('headers', 'true').lower() if headers == 'true': headers = True else: headers = False # write the output flex.output.content_type = 'application/json' flex.output.write('[') first_row = True if headers is True: result = json.dumps(properties) first_row = False flex.output.write(result) for item in get_data(params, limit): result = json.dumps([(item.get(p) or '') for p in properties]) if first_row is False: result = ',' + result first_row = False flex.output.write(result) flex.output.write(']')
def flexio_handler(flex): # get the input input = flex.input.read() input = json.loads(input) if not isinstance(input, list): raise ValueError # define the expected parameters and map the values to the parameter names # based on the positions of the keys/values params = OrderedDict() params['urls'] = { 'required': True, 'validator': validator_list, 'coerce': to_list } #params['columns'] = {'required': True, 'validator': validator_list, 'coerce': to_list} input = dict(zip(params.keys(), input)) # validate the mapped input against the validator v = Validator(params, allow_unknown=True) input = v.validated(input) if input is None: raise ValueError urls = input['urls'] loop = asyncio.get_event_loop() temp_fp_all = loop.run_until_complete(fetch_all(urls)) flex.output.content_type = 'application/json' flex.output.write('[') # get the columns for each of the input urls properties = [] for temp_fp in temp_fp_all: try: fp = io.TextIOWrapper(temp_fp, encoding='utf-8-sig') reader = csv.DictReader(fp, delimiter=',', quotechar='"') for row in reader: properties = list(row.keys()) break finally: fp.seek(0) fp.detach() flex.output.write(json.dumps(properties)) for temp_fp in temp_fp_all: fp = io.TextIOWrapper(temp_fp, encoding='utf-8-sig') reader = csv.DictReader(fp, delimiter=',', quotechar='"') for row in reader: row = ',' + json.dumps([(row.get(p) or '') for p in properties]) flex.output.write(row) temp_fp.close() flex.output.write(']')
def flexio_handler(flex): # get the input input = flex.input.read() try: input = json.loads(input) if not isinstance(input, list): raise ValueError except ValueError: raise ValueError # define the expected parameters and map the values to the parameter names # based on the positions of the keys/values params = OrderedDict() params['urls'] = {'required': True, 'validator': validator_list, 'coerce': to_list} params['search'] = {'required': True, 'type': 'string'} params['properties'] = {'required': False, 'validator': validator_list, 'coerce': to_list, 'default': '*'} input = dict(zip(params.keys(), input)) # validate the mapped input against the validator v = Validator(params, allow_unknown = True) input = v.validated(input) if input is None: raise ValueError # get the urls to process search_urls = input['urls'] search_urls = [s.strip() for s in search_urls] # get the search term to use to find the corresponding links search_text = input['search'] search_text = " ".join(search_text.split()).lower().strip() # remove leading/trailing/duplicate spaces and convert to lowercase # get the properties to return and the property map property_map = OrderedDict() property_map['domain'] = 'domain' property_map['link'] = 'link' property_map['text'] = 'text' properties = [p.lower().strip() for p in input['properties']] # if we have a wildcard, get all the properties if len(properties) == 1 and properties[0] == '*': properties = list(property_map.keys()) loop = asyncio.get_event_loop() result = loop.run_until_complete(fetch_all(search_urls, search_text, properties)) # if we don't have any results, return an empty result if len(result) == 0: result = [['']] # return the results result = json.dumps(result, default=to_string) flex.output.content_type = "application/json" flex.output.write(result)
def update_service(curr_id): v = Validator(purge_unknown=True) schema = { 'name': { 'type': 'string' }, 'price': { 'type': 'float' }, 'description': { 'type': 'string' }, 'duration': { 'coerce': lambda x: timedelta(hours=parse(x).hour, minutes=parse(x).minute), }, 'performers': { 'type': 'list' } } req_data = v.validated(request.get_json(), schema) if not req_data: abort(400, v.errors) service = Service.get(curr_id) if not service: return jsonify( {"msg": "{0} doesn't exist".format(type(service).__name__)}), 400 if 'performers' in req_data.keys(): old_performers = set(map(lambda x: x.id, service.performers)) new_performers = set(req_data['performers']) to_remove = old_performers.difference(new_performers) to_add = new_performers.difference(old_performers) try: if len(to_remove): db.session.execute(performer_service.delete().where( and_(performer_service.c.service_id == curr_id, performer_service.c.performer_id.in_(to_remove)))) if len(to_add): db.session.execute(performer_service.insert(), [{ 'performer_id': x, 'service_id': curr_id } for x in to_add]) except: db.session.rollback() return jsonify({"msg": "Probably performers parameter is invalid"}), 400 return update( service, {key: req_data[key] for key in req_data if key != 'performers'})
def validate_schema(schema_id, data): """ Generic schema validation function. :param str schema_id: Name of the schema to validate against. :param dict data: Data to validate. :return: A tuple of a dictionary with validated and coersed data and the validation errors found, if any. :rtype: tuple """ validator = Validator(SCHEMAS[schema_id]) validated = validator.validated(data) return validated, validator.errors
def create_service(): v = Validator(purge_unknown=True) schema = { 'name': { 'type': 'string', 'required': True }, 'price': { 'coerce': float, 'required': True }, 'description': { 'type': 'string', 'required': True }, 'duration': { 'required': True, 'coerce': lambda x: timedelta(hours=parse(x).hour, minutes=parse(x).minute) }, 'performers': { 'type': 'list' } } req_data = v.validated(request.get_json(), schema) if not req_data: abort(400, v.errors) service = db.session.query(Service).filter( Service.name == req_data['name']).first() if service: return jsonify({"msg": "Service already exists"}), 400 service = Service(business_id=Business.get(get_jwt_claims()['id']).id) msg = add(service, {key: req_data[key] for key in req_data if key != 'performers'}) try: if 'performers' in req_data.keys() and len(req_data['performers']) > 0: db.session.execute(performer_service.insert(), [{ 'performer_id': x, 'service_id': service.id } for x in req_data['performers']]) db.session.commit() except: db.session.rollback() return jsonify({"msg": "Probably performers parameter is invalid"}), 400 return msg
def validated_method_example(): """validated能返回验证后的document, 下面的代码给出了一种对输入的数据流进行处理的例子。 """ schema = {"value": {"type": "number"}} v = Validator(schema) documents = [ {"value": 1}, {"value": [1, 2, 3]}, {"value": 2}, ] valid_documents = [x for x in [v.validated(y) for y in documents] if x is not None] print(valid_documents) # validated_method_example()
def create_appointment(): v = Validator(purge_unknown=True) schema = { 'service_id': { 'coerce': int, 'required': True }, 'performer_id': { 'coerce': int, 'required': True }, 'date': { 'coerce': lambda x: parse(x).isoformat(), 'required': True }, 'user_id': { 'coerce': lambda x: int(x) if x else None, 'default': None, 'nullable': True }, 'notes': { 'type': 'string' }, 'coordx': { 'type': 'float' }, 'coordy': { 'type': 'float' } } req_data = v.validated(request.get_json(), schema) if not req_data: abort(400, v.errors) user_id = get_jwt_claims()['id'] if get_jwt_claims()['role'] == 'business': business = db.session.query(Business).filter( Business.user_id == user_id).first() if business.id != Performer.get(req_data['performer_id']).business_id: abort(403) if business.id != Service.get(req_data['service_id']).business_id: abort(403) user_id = req_data['user_id'] appointment = Appointment(user_id=user_id, is_confirmed=False) return add(appointment, {key: req_data[key] for key in req_data if key != 'user_id'})
def flexio_handler(flex): # get the input input = flex.input.read() try: input = json.loads(input) if not isinstance(input, list): raise ValueError except ValueError: raise ValueError # define the expected parameters and map the values to the parameter names # based on the positions of the keys/values params = OrderedDict() params['cur'] = { 'required': True, 'validator': validate_currency, 'coerce': lambda s: s.upper() } params['date'] = {'required': False, 'type': 'date', 'coerce': to_date} input = dict(zip(params.keys(), input)) # validate the mapped input against the validator # if the input is valid return an error v = Validator(params, allow_unknown=True) input = v.validated(input) if input is None: raise ValueError date = 'latest' if 'date' in input.keys(): date = input['date'].strftime('%Y-%m-%d') url = 'https://api.exchangeratesapi.io/' + date + '?base=' + input['cur'] response = requests_retry_session().get(url) rates = response.json()['rates'] items = list() for currency, amount in rates.items(): items.append([currency, amount]) items = sorted(items, key=itemgetter(0)) result = [['currency', 'amount']] result.extend(items) flex.output.content_type = "application/json" flex.output.write(result)
def update_appointment(curr_id): v = Validator(purge_unknown=True) schema = { 'service_id': { 'coerce': int, }, 'performer_id': { 'coerce': int, }, 'date': { 'coerce': lambda x: parse(x).isoformat(), }, 'notes': { 'type': 'string' }, 'coordx': { 'type': 'float' }, 'coordy': { 'type': 'float' } } req_data = v.validated(request.get_json(), schema) if not req_data: abort(400, v.errors) user_id = get_jwt_claims()['id'] appointment = Appointment.get(curr_id) if not appointment: abort(404) if get_jwt_claims()['role'] == 'user': if appointment.user.id != user_id: abort(403) else: business = appointment.service.business if business.id != db.session.query(Business).filter( Business.user_id == user_id).first().id: abort(403) if 'performer_id' in req_data.keys(): if business.id != Performer.get( req_data['performer_id']).business_id: abort(403) if 'service_id' in req_data.keys(): if business.id != Service.get(req_data['service_id']).business_id: abort(403) return update(appointment, req_data)
def post(self): """ :return: """ v = Validator(translation_schema) args = v.validated(request.get_json()) if args is None: return ApiResponse(status=4001, errors=v.errors) text = args.get(u'text') lang = self.ts.detect(text) return { u'lang': lang }
def update_business(): v = Validator(purge_unknown=True) schema = { 'name': { 'type': 'string' }, 'phone': { 'type': 'string' # 'regex': REGEX_PHONE }, 'address': { 'type': 'string' } } req_data = v.validated(request.get_json(), schema) if not req_data: abort(400, v.errors) return update(Business.get(get_jwt_claims()['id']), req_data)
def post(self): us = ServiceLocator.resolve(ServiceLocator.USERS) ss = ServiceLocator.resolve(ServiceLocator.SESSIONS) v = Validator(user_schema) args = v.validated(request.get_json()) if args is None: return ApiResponse(status=4001, errors=v.errors) login = args.get('login') email = args.get('email') password = args.get('password') first_name = args.get('first_name', '') last_name = args.get('last_name', '') try: us.check(login, email) user = us.create(login, email, password, first_name=first_name, last_name=last_name) # Create session token = us.make_auth_token(user) ss.create(user, token) user['auth_token'] = token return user except LoginAlreadyExists as ex: error(u'UserService.signup({0})'.format(login), ex) return ApiResponse(status=4001, errors=errors.SignErrors.login_already_exists(['login'])) except EmailAlreadyExists as ex: error(u'UserService.signup({0})'.format(email), ex) return ApiResponse(status=4001, errors=errors.SignErrors.email_already_exists(['email'])) except Exception as ex: error(u'UserSignUpAPI -> us.create({0})'.format(login), ex) return ApiResponse(status=500, errors=errors.ServerErrors.internal_server_error([]))
def login(): v = Validator(purge_unknown=True) schema = { 'email': { 'type': 'string', 'required': True # 'regex': REGEX_EMAIL }, 'password': { 'required': True, 'type': 'string' } } req_data = v.validated(request.get_json(), schema) if not req_data: abort(400, v.errors) user = User.query.filter(User.email == req_data['email']).first() if not (user and user.check_password(req_data['password'])): return jsonify({"msg": "Failed to log in"}), 401 access_token = create_access_token(identity=user.id) return jsonify(access_token=access_token), 200
def post(self): """ Translate text :return: """ v = Validator(translation_schema) args = v.validated(request.get_json()) if args is None: return ApiResponse(status=4001, errors=v.errors) text = args.get(u'text') user = self.ss.get_user() try: translation = self.ts.translate(text, user.direction) return translation except Exception as ex: error(u'TranslationsAPI.post(text={0}, dir={1})'.format(text, user.direction), ex) return ApiResponse(status=500, errors=ServerErrors.internal_server_error([]))
def patch(self, card_id): u""" Update card entity :param card_id: card's id :return: updated card """ v = Validator(card_schema) args = v.validated(request.get_json()) if args is None: return ApiResponse(status=4001, errors=v.errors) user = self.ss.get_user() card = self.cs.get(user, ObjectId(card_id)) if card is None: return ApiResponse(status=404, errors=CardsErrors.card_dont_exists([])) foreign = args.get(u'foreign') native = args.get(u'native') transcription = args.get(u'transcription', card.transcription) context = args.get(u'context', card.foreign_context) duplicate_card = self.cs.single(user, foreign, user.foreign_lng) if duplicate_card.id != card.id: return ApiResponse(status=409, errors=CardsErrors.card_already_exists(foreign, [u'foreign'])) try: card.foreign = foreign card.native = native card.transcription = transcription card.context = context card.save() except Exception as ex: error(u'CardApi.patch(card_id={0})'.format(card_id), ex) return ApiResponse(status=500, errors=ServerErrors.internal_server_error([]))
def normalize_and_validate(dict_to_check, schema): # type: (dict, dict) -> (dict) """Normalize and validate a dictionary, will raise if invalid Args: dict_to_check(dict): dictionary to check schema(dict): schema to use Returns: dict: Normalized and valid dictionary Raises: SchemaMisMatch: """ c_validator = Validator(schema, allow_unknown=True) valid_dict = c_validator.validated(dict_to_check, normalize=True) if valid_dict is None: raise SchemaMisMatch(c_validator.errors) return valid_dict
def normalize_validate_config(config_data, strict_validation=False): """ Normalize and validate endpoints :param config_data: dictionary with endpoints :param strict_validation: whether to fail in the case of bad configuration entry :return: dictionary with normalized and validated endpoints """ validated_config_data = dict() v = Validator(endpoint_schema) error_str = None error_list = list() for endpoint_key, endpoint_value in config_data.items(): normalized_item = v.normalized(endpoint_value) validated_endpoint = v.validated(normalized_item) if validated_endpoint is None: error_str = "Schema failed to validate for endpoint {0}, removing it. Errors: {1}".format( endpoint_key, json.dumps(v.errors, indent=2, sort_keys=True)) error_list.append(error_str) logger.error(error_str) else: validated_config_data[endpoint_key] = validated_endpoint logger.debug("Original configuration:") for k, v in config_data.items(): logger.debug("{0}: {1}".format(k, json.dumps(v, indent=2, sort_keys=True))) logger.debug("Normalized configuration:") for k, v in validated_config_data.items(): logger.debug("{0}: {1}".format(k, json.dumps(v, indent=2, sort_keys=True))) if strict_validation and len(error_list) > 0: raise InvalidConfigurationError("\n".join(error_list)) return validated_config_data
def post(self): """ Translate text :return: """ v = Validator(picture_schema) args = v.validated(request.get_json()) if args is None: return ApiResponse(status=4001, errors=v.errors) text = args.get(u'text') try: picture = self.ps.get(text) if picture: return picture return self.ps.add(text, self.gs.random(text)) except Exception as ex: error(u'PicturesRandomAPI.post(text={0})'.format(text), ex) return ApiResponse(status=500, errors=ServerErrors.internal_server_error([]))
def validate(self, userconf): """ Validate the given user configuration dictionary with the declared config handled by this configurator. :raise MissingOptions: if mandatory options are missing. :raise UnknownOptions: if non declared options are present. :param dict userconf: The user configuration. :return: A custom named tuple that maps the config keys with another named tuple that holds the name of the key, the value and the flag marking it as secret or not. :rtype: namedtuple """ if not self._declared: self._configtype = namedtuple('config', []) return self._configtype() # All mandatory keys are present in user config mandatory = { key for key, info in self._declared.items() if not info['optional'] } available = set(userconf.keys()) if mandatory - available: raise MissingOptions(sorted(mandatory - available)) # Check for unknown configuration options declared = set(self._declared.keys()) if available - declared: raise UnknownOptions(sorted(available - declared)) # Check schema of the options for key, info in self._declared.items(): schema = info['schema'] if key in userconf and schema is not None: validator = Validator({key: schema}) validated = validator.validated({key: userconf[key]}) if validated is None: log.critical('Invalid config option {} = {}:\n{}'.format( key, userconf[key], pformat(validator.errors))) raise SyntaxError('Invalid config option {} = {}'.format( key, userconf[key])) userconf[key] = validated[key] # Add missing default values validated = deepcopy(userconf) validated.update({ key: info['default'] for key, info in self._declared.items() if key not in available }) # Pass custom validators for validator in self._validators: validator(validated) # Log configuration def is_secret(key): return self._declared[key]['secret'] log_config = [] for key in self._declared.keys(): # Allow custom validators to delete keys if key not in validated: continue if is_secret(key): log_config.append('{} = {}'.format(key, '*' * 20)) continue log_config.append('{} = {}'.format(key, validated[key])) log.info('Using configuration:\n {}'.format( '\n '.join(log_config))) # Create configuration type for this declared configuration self._configtype = namedtuple('config', validated.keys()) # Create inmutable configuration object return self._configtype( **{ key: self._configitem( key=key, value=value, is_secret=is_secret(key)) for key, value in validated.items() })
def flexio_handler(flex): # get the api key from the variable input auth_token = dict(flex.vars).get('hunter_api_key') if auth_token is None: raise ValueError # get the input input = flex.input.read() input = json.loads(input) if not isinstance(input, list): raise ValueError # define the expected parameters and map the values to the parameter names # based on the positions of the keys/values params = OrderedDict() params['email'] = {'required': True, 'type': 'string'} params['properties'] = {'required': False, 'validator': validator_list, 'coerce': to_list, 'default': '*'} input = dict(zip(params.keys(), input)) # validate the mapped input against the validator # if the input is valid return an error v = Validator(params, allow_unknown = True) input = v.validated(input) if input is None: raise ValueError # map this function's property names to the API's property names property_map = OrderedDict() property_map['score'] = 'score' property_map['status'] = 'result' property_map['regexp'] = 'regexp' property_map['autogen'] = 'gibberish' property_map['disposable'] = 'disposable' property_map['webmail'] = 'webmail' property_map['mx_records'] = 'mx_records' property_map['smtp_server'] = 'smtp_server' property_map['smtp_check'] = 'smtp_check' property_map['smtp_check_blocked'] = 'block' property_map['smtp_accept_all'] = 'accept_all' # get the properties to return and the property map; # if we have a wildcard, get all the properties properties = [p.lower().strip() for p in input['properties']] if len(properties) == 1 and (properties[0] == '' or properties[0] == '*'): properties = list(property_map.keys()) # see here for more info: # https://hunter.io/api/docs#email-verifier url_query_params = { 'email': input['email'], 'api_key': auth_token } url_query_str = urllib.parse.urlencode(url_query_params) url = 'https://api.hunter.io/v2/email-verifier?' + url_query_str # get the response data as a JSON object response = requests_retry_session().get(url) response.raise_for_status() content = response.json() content = content.get('data', {}) # get the properties result = [[content.get(property_map.get(p,''),'') for p in properties]] # don't use "or '' for p in properties" because result can be true/false # return the results result = json.dumps(result, default=to_string) flex.output.content_type = "application/json" flex.output.write(result)
def flexio_handler(flex): # get the api key from the variable input auth_token = dict(flex.vars).get('quandl_api_key') if auth_token is None: raise ValueError # get the input input = flex.input.read() try: input = json.loads(input) if not isinstance(input, list): raise ValueError except ValueError: raise ValueError # define the expected parameters and map the values to the parameter names # based on the positions of the keys/values params = OrderedDict() params['name'] = {'required': True, 'type': 'string', 'coerce': str} params['properties'] = { 'required': False, 'validator': validator_list, 'coerce': to_list, 'default': '*' } params['mindate'] = { 'required': False, 'type': 'date', 'default': '1900-01-01', 'coerce': to_date } params['maxdate'] = { 'required': False, 'type': 'date', 'default': '2099-12-31', 'coerce': to_date } input = dict(zip(params.keys(), input)) # validate the mapped input against the validator # if the input is valid return an error v = Validator(params, allow_unknown=True) input = v.validated(input) if input is None: raise ValueError # make the request # see here for more info: https://docs.quandl.com/ url_query_params = { "api_key": auth_token, "start_date": input['mindate'], "end_date": input['maxdate'] } url_query_str = urllib.parse.urlencode(url_query_params) url = 'https://www.quandl.com/api/v3/datasets/' + input[ 'name'] + '?' + url_query_str headers = {'Accept': 'application/json'} response = requests_retry_session().get(url, headers=headers) response.raise_for_status() content = response.json() # get the columns and rows; clean up columns by converting them to # lowercase and removing leading/trailing spaces rows = content.get('dataset', {}).get('data', []) columns = content.get('dataset', {}).get('column_names', []) columns = [c.lower().strip() for c in columns] # get the properties (columns) to return based on the input; # if we have a wildcard, get all the properties properties = [p.lower().strip() for p in input['properties']] if len(properties) == 1 and properties[0] == '*': properties = columns # build up the result result = [] result.append(properties) for r in rows: item = dict( zip(columns, r) ) # create a key/value for each column/row so we can return appropriate columns item_filtered = [item.get(p) or '' for p in properties] result.append(item_filtered) result = json.dumps(result, default=to_string) flex.output.content_type = "application/json" flex.output.write(result)
def flexio_handler(flex): # TODO: support language language = 'en' # get the input input = flex.input.read() try: input = json.loads(input) if not isinstance(input, list): raise ValueError except ValueError: raise ValueError # define the expected parameters and map the values to the parameter names # based on the positions of the keys/values params = OrderedDict() params['search'] = {'required': True, 'type': 'string'} input = dict(zip(params.keys(), input)) # validate the mapped input against the validator # if the input is valid return an error v = Validator(params, allow_unknown=True) input = v.validated(input) if input is None: raise ValueError # see here for more info: https://en.wikipedia.org/w/api.php?action=help&modules=query # see here to experiment with the api: https://en.wikipedia.org/wiki/Special:ApiSandbox # STEP 1: perform a search and get the page id for the top item in the search url_query_params = { 'action': 'query', 'format': 'json', 'list': 'search', 'srprop': 'timestamp', 'srsearch': input['search'] } url_query_str = urllib.parse.urlencode(url_query_params) url = 'https://en.wikipedia.org/w/api.php?' + url_query_str response = requests_retry_session().get(url) search_info = response.json() search_items = search_info.get('query', {}).get('search', []) top_search_item = {} if len(search_items) > 0: top_search_item = search_items[0] top_search_item_page_id = top_search_item.get('pageid') if top_search_item_page_id is None: flex.output.content_type = "application/json" flex.output.write([[""]]) return # STEP 2: get the article for the page id returned by the search top_search_item_page_id = str(top_search_item_page_id) url = 'https://en.wikipedia.org/w/api.php?format=json&action=query&prop=extracts&explaintext=&exintro=&exsentences=1&pageids=' + top_search_item_page_id response = requests_retry_session().get(url) article_info = response.json() extract = article_info.get('query', {}).get('pages', {}).get(top_search_item_page_id, {}).get('extract', '') result = [[extract]] flex.output.content_type = "application/json" flex.output.write(result)
class TestCerberus: package = 'cerberus' version = str(__version__) def __init__(self, allow_extra): schema = { 'id': { 'type': 'integer', 'required': True }, 'client_name': { 'type': 'string', 'maxlength': 255, 'required': True }, 'sort_index': { 'type': 'float', 'required': True }, 'client_phone': { 'type': 'string', 'maxlength': 255, 'nullable': True }, 'location': { 'type': 'dict', 'schema': { 'latitude': { 'type': 'float' }, 'longitude': { 'type': 'float' } }, 'nullable': True, }, 'contractor': { 'type': 'integer', 'min': 0, 'nullable': True, 'coerce': int }, 'upstream_http_referrer': { 'type': 'string', 'maxlength': 1023, 'nullable': True }, 'grecaptcha_response': { 'type': 'string', 'minlength': 20, 'maxlength': 1000, 'required': True }, 'last_updated': { 'type': 'datetime', 'nullable': True, 'coerce': datetime_parse }, 'skills': { 'type': 'list', 'default': [], 'schema': { 'type': 'dict', 'schema': { 'subject': { 'type': 'string', 'required': True }, 'subject_id': { 'type': 'integer', 'required': True }, 'category': { 'type': 'string', 'required': True }, 'qual_level': { 'type': 'string', 'required': True }, 'qual_level_id': { 'type': 'integer', 'required': True }, 'qual_level_ranking': { 'type': 'float', 'default': 0, 'required': True }, }, }, }, } self.v = Validator(schema) self.v.allow_unknown = allow_extra def validate(self, data): validated = self.v.validated(data) if validated is None: return False, self.v.errors else: return True, validated
def flexio_handler(flex): # TODO: support language language = 'en' # get the input input = flex.input.read() try: input = json.loads(input) if not isinstance(input, list): raise ValueError except ValueError: raise ValueError # define the expected parameters and map the values to the parameter names # based on the positions of the keys/values params = OrderedDict() params['search'] = {'required': True, 'type': 'string'} params['properties'] = { 'required': False, 'validator': validator_list, 'coerce': to_list, 'default': 'description' } input = dict(zip(params.keys(), input)) # validate the mapped input against the validator # if the input is valid return an error v = Validator(params, allow_unknown=True) input = v.validated(input) if input is None: raise ValueError default_properties = OrderedDict() default_properties['label'] = '' default_properties['description'] = '' default_properties['wikipedia_url'] = '' default_properties['gender'] = '' default_properties['birth_name'] = '' default_properties['given_name'] = '' default_properties['family_name'] = '' default_properties['native_name'] = '' default_properties['birth_date'] = '' default_properties['death_date'] = '' default_properties['birth_place'] = '' default_properties['death_place'] = '' default_properties['religion'] = '' default_properties['citizenship'] = '' default_properties['native_language'] = '' default_properties['father'] = '' default_properties['mother'] = '' default_properties['spouse'] = '' default_properties['residence'] = '' default_properties['occupation'] = '' default_properties['education'] = '' default_properties['net_worth'] = '' default_properties['twitter_id'] = '' default_properties['instagram_id'] = '' default_properties['reddit_id'] = '' default_properties['bloomberg_id'] = '' default_properties['updated_dt'] = '' # see here for general information about the wikidata api: https://www.wikidata.org/wiki/Wikidata:Data_access # see here for list of sorted properties: https://www.wikidata.org/wiki/MediaWiki:Wikibase-SortedProperties # STEP 1: make an initial search request to find the most relevant item # https://www.wikidata.org/w/api.php?action=wbsearchentities&language=en&search=:search_term url_query_params = { 'action': 'wbsearchentities', 'language': language, 'format': 'json', 'search': input['search'] } url_query_str = urllib.parse.urlencode(url_query_params) url = 'https://www.wikidata.org/w/api.php?' + url_query_str response = requests_retry_session().get(url) search_info = response.json() search_items = search_info.get('search', []) if len(search_items) == 0: flex.output.content_type = "application/json" flex.output.write([[""]]) return search_first_item_id = search_items[0].get('id', '') # STEP 2: get the info about the item # https://www.wikidata.org/w/api.php?action=wbgetentities&sites=enwiki&props=claims&format=json&ids=:id props = 'info|sitelinks|sitelinks/urls|labels|descriptions|claims|datatype' url_query_params = { 'action': 'wbgetentities', 'sites': 'enwiki', 'props': props, 'format': 'json', 'ids': search_first_item_id } url_query_str = urllib.parse.urlencode(url_query_params) url = 'https://www.wikidata.org/w/api.php?' + url_query_str response = requests_retry_session().get(url) content = response.json() # TODO: # confirm we have a human # instanceof (P31) is Q5 (human) # STEP 3: get primary item info and additional info item_primary_info = get_basic_info(content, search_first_item_id, language) item_claim_info = get_claim_info(content, search_first_item_id, language) # STEP 4: make an additional lookup to find out the info from the wikipedia entity values # https://www.wikidata.org/w/api.php?action=wbgetentities&sites=enwiki&props=claims&format=json&ids=:id props = 'labels' search_ids = [ i.get('datavalue', {}).get('value', {}).get('id', '') for i in item_claim_info if i.get('datavalue', {}).get('type') == 'wikibase-entityid' ] search_ids = '|'.join(search_ids) url_query_params = { 'action': 'wbgetentities', 'sites': 'enwiki', 'props': props, 'format': 'json', 'ids': search_ids } url_query_str = urllib.parse.urlencode(url_query_params) url = 'https://www.wikidata.org/w/api.php?' + url_query_str response = requests_retry_session().get(url) content = response.json() # STEP 5: use the info from the additional lookup to populate the values in the item info item_claim_info_enriched = [ update_claim_info(i, content, language) for i in item_claim_info ] # STEP 6: merge the primary info and the enriched info item_info_lookup = {} for i in item_primary_info: item_info_lookup[i['name']] = i.get('value', '') for i in item_claim_info: item_info_lookup[i['name']] = i.get('value', '') # get the properties to return properties = [p.lower().strip() for p in input['properties']] # if we have a wildcard, get all the properties if len(properties) == 1 and properties[0] == '*': properties = list(default_properties.keys()) # build up the result result = [[item_info_lookup.get(p, '') or '' for p in properties]] # return the results result = json.dumps(result, default=to_string) flex.output.content_type = "application/json" flex.output.write(result)
def validate_booking_data(booking_data: dict) -> dict: validator = Validator(BOOKING_DATA_SCHEMA) validated_data = validator.validated(booking_data) if validated_data is None: raise RuntimeError('Validation for booking data was failed. : ' + str(validator.errors)) return validated_data
def flexio_handler(flex): # get the api key from the variable input auth_token = dict(flex.vars).get('producthunt_connection', {}).get('access_token') if auth_token is None: raise ValueError # get the input input = flex.input.read() try: input = json.loads(input) if not isinstance(input, list): raise ValueError except ValueError: raise ValueError # define the expected parameters and map the values to the parameter names # based on the positions of the keys/values params = OrderedDict() params['properties'] = { 'required': False, 'validator': validator_list, 'coerce': to_list, 'default': '*' } input = dict(zip(params.keys(), input)) # validate the mapped input against the validator # if the input is valid return an error v = Validator(params, allow_unknown=True) input = v.validated(input) if input is None: raise ValueError # map this function's property names to the API's property names property_map = OrderedDict() property_map['id'] = 'id' property_map['name'] = 'name' property_map['createdAt'] = 'createdAt' property_map['featuredAt'] = 'featuredAt' property_map['url'] = 'url' property_map['tagline'] = 'tagline' property_map['description'] = 'description' # make the request # see here for more info: https://api.producthunt.com/v2/docs url = 'https://api.producthunt.com/v2/api/graphql' headers = { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + auth_token, 'Host': 'api.producthunt.com' } columns = list(property_map.values()) data = { "query": "query { posts { edges { node {" + " ".join(columns) + " } } } }" } response = requests_retry_session().post(url, data=json.dumps(data), headers=headers) response.raise_for_status() content = response.json() # get the properties to return and the property map properties = [p.lower().strip() for p in input['properties']] # if we have a wildcard, get all the properties if len(properties) == 1 and properties[0] == '*': properties = list(property_map.keys()) # build up the result result = [] result.append(properties) edges = content.get('data', {}).get('posts', {}).get('edges', []) for item in edges: row = [ item.get('node').get(property_map.get(p, '')) or '' for p in properties ] result.append(row) flex.output.content_type = "application/json" flex.output.write(result)
def create_performer(): v = Validator(purge_unknown=True) schema = { 'name': { 'type': 'string', 'required': True }, 'phone': { 'type': 'string', 'required': True # 'regex' : REGEX_PHONE }, 'description': { 'type': 'string', 'required': True }, 'photo': {}, 'services': { 'type': 'list' }, 'work_beg': { 'coerce': lambda x: timedelta(hours=parse(x).hour, minutes=parse(x).minute) }, 'work_end': { 'coerce': lambda x: timedelta(hours=parse(x).hour, minutes=parse(x).minute) }, 'lunch_beg': { 'coerce': lambda x: timedelta(hours=parse(x).hour, minutes=parse(x).minute) }, 'lunch_end': { 'coerce': lambda x: timedelta(hours=parse(x).hour, minutes=parse(x).minute) }, 'non_working_days': { 'type': 'list', 'default': [] } } req_data = v.validated(request.get_json(), schema) if not req_data: abort(400, v.errors) performer = db.session.query(Performer).filter( Performer.name == req_data['name']).first() if performer: return jsonify({"msg": "Performer already exists"}), 400 performer = Performer(business_id=Business.get(get_jwt_claims()['id']).id) if ('photo' in req_data.keys()) and req_data['photo']: photo = Image(data=req_data['photo']) db.session.add(photo) db.session.commit() performer.photo_id = photo.id msg = add(performer, { key: req_data[key] for key in req_data if key not in ['services', 'photo'] }) try: if ('services' in req_data.keys()) and (len(req_data['services']) > 0): db.session.execute(performer_service.insert(), [{ 'performer_id': performer.id, 'service_id': x } for x in req_data['services']]) db.session.commit() except: return jsonify({"msg": "Probably services parameter is invalid"}), 400 return msg
def update_performer(curr_id): v = Validator(purge_unknown=True) schema = { 'name': { 'type': 'string' }, 'phone': { 'type': 'string' # 'regex' : REGEX_PHONE }, 'description': { 'type': 'string' }, 'newPhoto': {}, 'services': { 'type': 'list' }, 'work_beg': { 'coerce': lambda x: timedelta(hours=parse(x).hour, minutes=parse(x).minute) }, 'work_end': { 'coerce': lambda x: timedelta(hours=parse(x).hour, minutes=parse(x).minute) }, 'lunch_beg': { 'coerce': lambda x: timedelta(hours=parse(x).hour, minutes=parse(x).minute) }, 'lunch_end': { 'coerce': lambda x: timedelta(hours=parse(x).hour, minutes=parse(x).minute) }, 'non_working_days': { 'type': 'list', 'default': [] } } req_data = v.validated(request.get_json(), schema) if not req_data: abort(400, v.errors) performer = Performer.get(curr_id) if not performer: return jsonify( {"msg": "{0} doesn't exist".format(type(performer).__name__)}), 400 if 'services' in req_data.keys(): old_services = set(list(map(lambda x: x.id, performer.services))) new_services = set(req_data['services']) to_remove = old_services.difference(new_services) to_add = new_services.difference(old_services) try: if len(to_remove) > 0: db.session.execute(performer_service.delete().where( and_(performer_service.c.performer_id == curr_id, performer_service.c.service_id.in_(to_remove)))) if len(to_add) > 0: db.session.execute(performer_service.insert(), [{ 'performer_id': curr_id, 'service_id': x } for x in to_add]) except: db.session.rollback() return jsonify({"msg": "Probably performers parameter is invalid"}), 400 if 'photo' in req_data.keys(): if performer.photo_id: Image.query.filter(Image.id == performer.photo_id).delete() if req_data['photo']: photo = Image(data=req_data['photo']) db.session.add(photo) db.session.commit() performer.photo_id = photo.id return update(performer, { key: req_data[key] for key in req_data if key not in ['services', 'photo'] })
def flexio_handler(flex): # get the api key from the variable input auth_token = dict(flex.vars).get('fullcontact_api_key') if auth_token is None: raise ValueError # get the input input = flex.input.read() try: input = json.loads(input) if not isinstance(input, list): raise ValueError except ValueError: raise ValueError # define the expected parameters and map the values to the parameter names # based on the positions of the keys/values params = OrderedDict() params['email'] = {'required': True, 'type': 'string'} params['properties'] = { 'required': False, 'validator': validator_list, 'coerce': to_list, 'default': '*' } input = dict(zip(params.keys(), input)) # validate the mapped input against the validator # if the input is valid return an error v = Validator(params, allow_unknown=True) input = v.validated(input) if input is None: raise ValueError # map this function's property names to the API's property names property_map = OrderedDict() property_map['full_name'] = 'fullName' property_map['age_range'] = 'ageRange' property_map['gender'] = 'gender' property_map['location'] = 'location' property_map['title'] = 'title' property_map['organization'] = 'organization' property_map['twitter_url'] = 'twitter' property_map['facebook_url'] = 'facebook' property_map['linkedin_url'] = 'linkedin' property_map['bio'] = 'bio' property_map['avatar_url'] = 'avatar' # get the properties to return and the property map properties = [p.lower().strip() for p in input['properties']] # if we have a wildcard, get all the properties if len(properties) == 1 and properties[0] == '*': properties = list(property_map.keys()) # see here for more info: # https://docs.fullcontact.com/#person-enrichment # https://dashboard.fullcontact.com/api-ref#response-codes-&-errors data = json.dumps({'email': input['email'].lower().strip()}) headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + auth_token } url = 'https://api.fullcontact.com/v3/person.enrich' # get the response data as a JSON object response = requests_retry_session().post(url, data=data, headers=headers) # sometimes results are pending; for these, return text indicating # the result is pending so the user can refresh later to look for # the completed result status_code = response.status_code if status_code == 202: flex.output.content_type = "application/json" flex.output.write([['Result Pending...']]) return # if a result can't be found or wasn't formatted properly, # return a blank (equivalent to not finding a bad email address) if status_code == 400 or status_code == 404 or status_code == 422: flex.output.content_type = "application/json" flex.output.write([['']]) return # return an error for any other non-200 result response.raise_for_status() # limit the results to the requested properties content = response.json() properties = [ content.get(property_map.get(p, ''), '') or '' for p in properties ] result = [properties] # return the results result = json.dumps(result, default=to_string) flex.output.content_type = "application/json" flex.output.write(result)