datahub/utils/validator.py (57 lines of code) (raw):

#!/usr/bin/env python # -*- coding: utf-8 -*- # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. from __future__ import absolute_import, print_function import re from functools import wraps import six from funcsigs import signature from . import ErrorMessage from ..exceptions import InvalidParameterException PROJECT_NAME_REGULAR_EXPRESSION = r'^[a-zA-Z]+[a-zA-Z0-9_]*' TOPIC_NAME_REGULAR_EXPRESSION = r'^[a-zA-Z]+[a-zA-Z0-9_]*' PROJECT_NAME_MIN_LENGTH = 3 PROJECT_NAME_MAX_LENGTH = 32 TOPIC_NAME_MIN_LENGTH = 1 TOPIC_NAME_MAX_LENGTH = 128 def is_valid_str(text, regular_expression, min_length, max_length): if not text or not isinstance(text, six.string_types): return False if len(text) < min_length or len(text) > max_length: return False pattern = re.compile(regular_expression) result = pattern.match(text) return result is not None and len(result.group()) == len(text) def check_project_name_valid(project_name): return is_valid_str(project_name, PROJECT_NAME_REGULAR_EXPRESSION, PROJECT_NAME_MIN_LENGTH, PROJECT_NAME_MAX_LENGTH) def check_topic_name_valid(topic_name): return is_valid_str(topic_name, TOPIC_NAME_REGULAR_EXPRESSION, TOPIC_NAME_MIN_LENGTH, TOPIC_NAME_MAX_LENGTH) def check_empty(variable): return variable is None or not variable def check_type(variable, *args): for data_type in args: if isinstance(variable, data_type): return True return False def check_negative(variable): return variable < 0 def check_positive(variable): return variable > 0 def type_assert(*type_args, **type_kwargs): def decorate(func): signature_ = signature(func) bound_types = signature_.bind_partial(*type_args, **type_kwargs).arguments @wraps(func) def wrapper(*args, **kwargs): bound_values = signature_.bind(*args, **kwargs) # Enforce type assertions across supplied arguments for name, value in bound_values.arguments.items(): if name in bound_types: # pre check for special argument if name == 'cursor' and type(value).__name__ == 'GetCursorResult': raise InvalidParameterException('param cursor should be type of str, get the cursor from ' 'getCursorResult') if not isinstance(value, bound_types[name]): # for python 2.7 if not (type(value).__name__ == "unicode" and (str in bound_types[name] if isinstance(bound_types[name], tuple) else bound_types[name] == str)): raise InvalidParameterException(ErrorMessage.INVALID_TYPE % (name, bound_types[name].__name__) + ", input is: " + type(value).__name__) return func(*args, **kwargs) return wrapper return decorate