def parse_api_spec(api_spec, api_version, resources): """ Dynamically create classes to interface with the Civis API. Parse an OpenAPI (Swagger) specification into a dictionary of classes where each class represents an endpoint resource and contains methods to make http requests on that resource. Parameters ---------- api_spec : OrderedDict The Civis API specification to parse. References should be resolved before passing, typically using jsonref.JsonRef(). api_version : string, optional The version of endpoints to call. May instantiate multiple client objects with different versions. Currently only "1.0" is supported. resources : string, optional When set to "base", only the default endpoints will be exposed in the client object. Set to "all" to include all endpoints available for a given user, including those that may be in development and subject to breaking changes at a later date. """ paths = api_spec['paths'] classes = {} for path, ops in paths.items(): base_path, methods = parse_path(path, ops, api_version, resources) class_name = to_camelcase(base_path) if methods and classes.get(base_path) is None: classes[base_path] = type(str(class_name), (Endpoint, ), {}) for method_name, method in methods: setattr(classes[base_path], method_name, method) return classes
def parse_service_api_spec(api_spec, root_path=None): """Dynamically create classes to interface with a Civis Service API. Parse an OpenAPI (Swagger) specification into a dictionary of classes where each class represents an endpoint resource and contains methods to make http requests on that resource. Parameters ---------- api_spec : OrderedDict The Civis Service API specification to parse. References should be resolved before passing, typically using jsonref.JsonRef(). root_path : str, optional An additional path for APIs that are not hosted on the service's root level. An example root_path would be '/api' for an app with resource endpoints that all begin with '/api'. """ paths = api_spec['paths'] classes = {} for path, ops in paths.items(): base_path, methods = _parse_service_path(path, ops, root_path=root_path) class_name = to_camelcase(base_path) if methods and classes.get(base_path) is None: classes[base_path] = type(str(class_name), (ServiceEndpoint, ), {}) for method_name, method in methods: setattr(classes[base_path], method_name, method) return classes
def test_tocamlecase(): test_cases = [ ('snake_case', 'SnakeCase'), ('Snake_Case', 'SnakeCase'), ('snakecase', 'Snakecase') ] for in_word, out_word in test_cases: assert to_camelcase(in_word) == out_word
def parse_path(path, operations, api_version, resources): """ Parse an endpoint into a class where each valid http request on that endpoint is converted into a convenience function and attached to the class as a method. """ path = path.strip('/') base_path = path.split('/')[0] class_name = to_camelcase(base_path) methods = [] if exclude_resource(path, api_version, resources): return class_name, methods for verb, op in operations.items(): method = parse_method(verb, op, path) if method is None: continue methods.append(method) return class_name, methods