def bind(self, **kwargs): """ Return a DataRep object by binding variables in the 'self' link. This method is used to instantiate concreate DataRep objects with fully qualified URIs based on the 'self' link associated with the jsonschema for this object. The `**kwargs` must match the parameters defined in the self link, if any. Example:: >>> book_schema = Schema(bookstore, book_jsonschema) >>> book1 = book_schema.bind(id=1) """ if 'self' not in self.jsonschema.links: raise LinkError("Cannot bind a schema that has no 'self' link") selflink = self.jsonschema.links['self'] valid_vars = uritemplate.variables(selflink.path.template) for k in kwargs.keys(): if k not in valid_vars: raise InvalidParameter( 'Invalid parameters "%s" for target link: %s' % (k, str(selflink))) (uri_path, values) = selflink.path.resolve(kvs=kwargs) uri = self.service.servicepath + uri_path[1:] return DataRep.from_schema(self.service, uri, jsonschema=self.jsonschema)
def rel(self, name, **kwargs): link = self.schema.get_link(name) method = link.get('method', 'get').lower() href = link.get('href', '') params = kwargs.get('params', {}) variables = uritemplate.variables(href) uri = self.expand_uri(name, **params) if not urlparse.urlparse(uri).netloc: uri = urlparse.urljoin(self.url, uri) if 'params' in kwargs: unused_params = { k: v for k, v in params.items() if k not in variables} kwargs['params'] = unused_params if "data" in kwargs and isinstance(kwargs.get("data"), Resource): resource = kwargs.get("data") kwargs["data"] = json.dumps(resource.data) schema_uri = resource.schema.url headers = kwargs.get('headers', {}) headers.setdefault('content-type', 'application/json; profile=' + schema_uri) kwargs['headers'] = headers return self.session.resource(uri, method=method, **kwargs)
def make_nav(link): '''Crafts the Navigators for each link''' if isinstance(link, list): return utils.LinkList((make_nav(lnk), lnk) for lnk in link) templated = link.get('templated', False) if not templated: uri = urlparse.urljoin(self.uri, link['href']) template_uri = None else: uri = None template_uri = urlparse.urljoin(self.uri, link['href']) cp = self._copy( uri=uri, template_uri=template_uri, templated=templated, title=link.get('title'), type=link.get('type'), profile=link.get('profile'), ) if templated: cp.uri = None cp.parameters = uritemplate.variables(cp.template_uri) else: cp.template_uri = None return cp
def _hydrate(cls, payload): """ Construct links for objects """ links = payload.pop('links', {}) for key, uri in links.iteritems(): variables = uritemplate.variables(uri) # marketplaces.card_holds collection, resource_type = key.split('.') item_attribute = item_property = resource_type # if parsed from uri then retrieve. e.g. customer.id for item in payload[collection]: # find type, fallback to Resource if we can't determine the # type e.g. marketplace.owner_customer collection_type = Resource.registry.get( resource_type, Resource) def extract_variables_from_item(item, variables): for v in variables: _, item_attribute = v.split('.') # HACK: https://github.com/PoundPay/balanced/issues/184 if item_attribute == 'self': item_attribute = 'id' item_value = item['links'].get( item_attribute, item.get(item_attribute)) if item_value: yield v, item_value item_variables = dict( extract_variables_from_item(item, variables)) # expand variables if we have them, else this is a link like # /debits if item_variables: parsed_link = uritemplate.expand(uri, item_variables) else: parsed_link = uri # check if this is a collection or a singular item if any( parsed_link.endswith(value) for value in item_variables.itervalues()): # singular if not item_property.endswith('_href'): item_property += '_href' lazy_href = parsed_link elif '{' in parsed_link and '}' in parsed_link: # the link is of the form /asdf/{asdf} which means # that the variables could not be resolved as it # was None. Instead of making it into a page object # we explicitly set it to None to represent the # attribute is None lazy_href = None else: # collection lazy_href = JSONSchemaCollection(collection_type, parsed_link) item.setdefault(item_property, lazy_href) return payload
def _get_parameters(self): def dict_helper(parameters): return {(p['name'], p['in']): p for p in parameters} override_parameters, excluded_parameters = self._process_override_parameters( ) override_parameters = dict_helper(override_parameters) # remove overridden path parameters beforehand so that there are no irrelevant warnings. path_variables = [ v for v in uritemplate.variables(self.path) if (v, 'path') not in override_parameters ] parameters = { **dict_helper(self._resolve_path_parameters(path_variables)), **dict_helper(self._get_filter_parameters()), **dict_helper(self._get_pagination_parameters()), **dict_helper(self._get_format_parameters()), } # override/add @extend_schema parameters for key in excluded_parameters: del parameters[key] for key, parameter in override_parameters.items(): parameters[key] = parameter return sorted(parameters.values(), key=lambda p: p['name'])
def rel(self, name, **kwargs): link = self.schema.get_link(name) method = link.get('method', 'get').lower() href = link.get('href', '') params = kwargs.get('params', {}) variables = uritemplate.variables(href) uri = self.expand_uri(name, **params) if not urlparse.urlparse(uri).netloc: uri = urlparse.urljoin(self.url, uri) if 'params' in kwargs: unused_params = { k: v for k, v in params.items() if k not in variables} kwargs['params'] = unused_params if "data" in kwargs: resource = kwargs.get("data") headers = kwargs.get('headers', {}) if isinstance(resource, Resource): kwargs["data"] = json.dumps(resource.data) headers.setdefault( 'content-type', self._get_content_type_for_resource(resource)) elif isinstance(resource, dict): kwargs["data"] = json.dumps(resource) headers.setdefault('content-type', 'application/json') kwargs['headers'] = headers return self.session.resource(uri, method=method, **kwargs)
def bind(self, **kwargs): """ Return a DataRep object by binding variables in the 'self' link. This method is used to instantiate concreate DataRep objects with fully qualified URIs based on the 'self' link associated with the jsonschema for this object. The `**kwargs` must match the parameters defined in the self link, if any. Example:: >>> book_schema = Schema(bookstore, book_jsonschema) >>> book1 = book_schema.bind(id=1) """ if 'self' not in self.jsonschema.links: raise LinkError("Cannot bind a schema that has no 'self' link") selflink = self.jsonschema.links['self'] valid_vars = uritemplate.variables(selflink.path.template) for k in kwargs.keys(): if k not in valid_vars: raise InvalidParameter( 'Invalid parameters "%s" for target link: %s' % (k, str(selflink))) (uri_path, values) = selflink.path.resolve(kvs=kwargs) uri = self.service.servicepath + uri_path[1:] return DataRep.from_schema(self.service, uri, jsonschema=self.jsonschema, path_vars=kwargs)
def get_path_parameters(self, path, method): """ Return a list of parameters from template path variables. """ parameters = [] for variable in uritemplate.variables(path): description = '' scheme_type = 'string' path_parameter = self.path_parameters.get(variable, None) if path_parameter: description = path_parameter.description scheme_type = path_parameter.scheme_type parameter = { "name": variable, "in": "path", "required": True, "description": description, 'schema': { 'type': scheme_type }, } parameters.append(parameter) return parameters
def validate(template, var_dict): """Returns True/False Tests whether a given dictionary `var_dict` is valid for a particular uri-template. """ temp_vars = variables(template) return temp_vars.issuperset(var_dict.keys())
def get_path_parameters(self, path, view_cls): """Return a list of Parameter instances corresponding to any templated path variables. :param str path: templated request path :param type view_cls: the view class associated with the path :return: path parameters :rtype: list[openapi.Parameter] """ parameters = [] queryset = get_queryset_from_view(view_cls) for variable in sorted(uritemplate.variables(path)): model, model_field = get_queryset_field(queryset, variable) attrs = get_basic_type_info(model_field) or {'type': openapi.TYPE_STRING} if getattr(view_cls, 'lookup_field', None) == variable and attrs['type'] == openapi.TYPE_STRING: attrs['pattern'] = getattr(view_cls, 'lookup_value_regex', attrs.get('pattern', None)) if model_field and getattr(model_field, 'help_text', False): description = model_field.help_text elif model_field and getattr(model_field, 'primary_key', False): description = get_pk_description(model, model_field) else: description = None field = openapi.Parameter( name=variable, description=force_real_str(description), required=True, in_=openapi.IN_PATH, **attrs ) parameters.append(field) return parameters
def _is_list_view(self, serializer=None): """ partially heuristic approach to determine if a view yields an object or a list of objects. used for operationId naming, array building and pagination. defaults to False if all introspection fail. """ if serializer is None: serializer = self.get_response_serializers() if isinstance(serializer, dict) and serializer: # extract likely main serializer from @extend_schema override serializer = {str(code): s for code, s in serializer.items()} serializer = serializer[min(serializer)] if isinstance(serializer, serializers.ListSerializer): return True if is_basic_type(serializer): return False if hasattr(self.view, 'action'): return self.view.action == 'list' # list responses are "usually" only returned by GET if self.method.lower() != 'get': return False if isinstance(self.view, ListModelMixin): return True # primary key/lookup variable in path is a strong indicator for retrieve if isinstance(self.view, GenericAPIView): lookup_url_kwarg = self.view.lookup_url_kwarg or self.view.lookup_field if lookup_url_kwarg in uritemplate.variables(self.path): return False return False
def _get_parameters(self): def dict_helper(parameters): return {(p['name'], p['in']): p for p in parameters} override_parameters = self._process_override_parameters() # remove overridden path parameters beforehand so that there are no irrelevant warnings. path_variables = [ v for v in uritemplate.variables(self.path) if (v, 'path') not in override_parameters ] parameters = { **dict_helper(self._resolve_path_parameters(path_variables)), **dict_helper(self._get_filter_parameters()), **dict_helper(self._get_pagination_parameters()), **dict_helper(self._get_format_parameters()), } # override/add/remove @extend_schema parameters for key, parameter in override_parameters.items(): if parameter is None: # either omit or explicitly remove parameter if key in parameters: del parameters[key] else: parameters[key] = parameter if callable(spectacular_settings.SORT_OPERATION_PARAMETERS): return sorted(parameters.values(), key=spectacular_settings.SORT_OPERATION_PARAMETERS) elif spectacular_settings.SORT_OPERATION_PARAMETERS: return sorted(parameters.values(), key=lambda p: p['name']) else: return list(parameters.values())
def get_path_parameters(self, path, view_cls): """Return a list of Parameter instances corresponding to any templated path variables. :param str path: templated request path :param type view_cls: the view class associated with the path :return: path parameters :rtype: list[openapi.Parameter] """ parameters = [] queryset = getattr(view_cls, 'queryset', None) model = getattr(getattr(view_cls, 'queryset', None), 'model', None) for variable in uritemplate.variables(path): model, model_field = get_queryset_field(queryset, variable) attrs = get_basic_type_info(model_field) or {'type': openapi.TYPE_STRING} if hasattr(view_cls, 'lookup_value_regex') and getattr(view_cls, 'lookup_field', None) == variable: attrs['pattern'] = view_cls.lookup_value_regex if model_field and model_field.help_text: description = force_text(model_field.help_text) elif model_field and model_field.primary_key: description = get_pk_description(model, model_field) else: description = None field = openapi.Parameter( name=variable, description=description, required=True, in_=openapi.IN_PATH, **attrs ) parameters.append(field) return parameters
def _parse_link(data, base_url=None): url = _get_string(data, 'href') url = urlparse.urljoin(base_url, url) if _get_bool(data, 'templated'): fields = [ Field(name, location='path') for name in uritemplate.variables(url) ] else: fields = None return Link(url=url, fields=fields)
def _hydrate(cls, payload): """ Construct links for objects """ links = payload.pop('links', {}) for key, uri in links.iteritems(): variables = uritemplate.variables(uri) # marketplaces.card_holds collection, resource_type = key.split('.') item_attribute = item_property = resource_type # if parsed from uri then retrieve. e.g. customer.id for item in payload[collection]: # find type, fallback to Resource if we can't determine the # type e.g. marketplace.owner_customer collection_type = Resource.registry.get(resource_type, Resource) def extract_variables_from_item(item, variables): for v in variables: _, item_attribute = v.split('.') # HACK: https://github.com/PoundPay/balanced/issues/184 if item_attribute == 'self': item_attribute = 'id' item_value = item['links'].get( item_attribute, item.get(item_attribute) ) if item_value: yield v, item_value item_variables = dict( extract_variables_from_item(item, variables)) # expand variables if we have them, else this is a link like # /debits if item_variables: parsed_link = uritemplate.expand(uri, item_variables) else: parsed_link = uri # check if this is a collection or a singular item if any( parsed_link.endswith(value) for value in item_variables.itervalues() ): # singular if not item_property.endswith('_href'): item_property += '_href' lazy_href = parsed_link else: # collection lazy_href = JSONSchemaCollection( collection_type, parsed_link) item.setdefault(item_property, lazy_href) return payload
def _vars_match_template(template, vars): """Validates that the provided variables match the template. :param template: The template :type template: str :param vars: The variables to match against the template :type vars: tuple or list :returns: bool""" keys = vars.keys() keys.sort() template_vars = list(uritemplate.variables(template)) template_vars.sort() return template_vars == keys
def _get_content(data, base_url, ref): content = {} links = _get_list(data, 'links') properties = _get_dict(data, 'properties') if properties: for key, value in properties.items(): if not isinstance(value, dict): continue if list(value.keys()) == ['$ref']: value = _dereference(value['$ref'], ref) sub_content = _get_content(value, base_url, ref) if sub_content: content[key] = sub_content if links: for link in get_dicts(links): rel = _get_string(link, 'rel') if rel: href = _get_string(link, 'href') method = _get_string(link, 'method') schema = _get_dict(link, 'schema') schema_type = _get_list(schema, 'type') schema_properties = _get_dict(schema, 'properties') schema_required = _get_list(schema, 'required') fields = [] url = urlparse.urljoin(base_url, href) templated = uritemplate.variables(url) for item in templated: orig = item if item.startswith('(') and item.endswith(')'): item = unquote(item.strip('(').rstrip(')')) if item.startswith('#/'): components = [ component for component in item.strip('#/').split('/') if component != 'definitions' ] item = '_'.join(components).replace('-', '_') url = url.replace(orig, item) fields.append( Field(name=item, location='path', required=True)) if schema_type == ['object'] and schema_properties: fields += [ Field(name=key, required=(key in schema_required)) for key in schema_properties.keys() ] if rel == 'self': rel = 'read' content[rel] = Link(url=url, action=method, fields=fields) return content
def path_reader(path): fields = list() for variable in uritemplate.variables(path): field = { 'name': variable, 'in': 'path', 'required': True, 'schema': { 'type': 'string' } } fields.append(field) return fields
def _get_content(data, base_url, ref): content = {} links = _get_list(data, 'links') properties = _get_dict(data, 'properties') if properties: for key, value in properties.items(): if not isinstance(value, dict): continue if list(value.keys()) == ['$ref']: value = _dereference(value['$ref'], ref) sub_content = _get_content(value, base_url, ref) if sub_content: content[key] = sub_content if links: for link in get_dicts(links): rel = _get_string(link, 'rel') if rel: href = _get_string(link, 'href') method = _get_string(link, 'method') schema = _get_dict(link, 'schema') schema_type = _get_list(schema, 'type') schema_properties = _get_dict(schema, 'properties') schema_required = _get_list(schema, 'required') fields = [] url = urlparse.urljoin(base_url, href) templated = uritemplate.variables(url) for item in templated: orig = item if item.startswith('(') and item.endswith(')'): item = urllib.unquote(item.strip('(').rstrip(')')) if item.startswith('#/'): components = [ component for component in item.strip('#/').split('/') if component != 'definitions' ] item = '_'.join(components).replace('-', '_') url = url.replace(orig, item) fields.append(Field(name=item, location='path', required=True)) if schema_type == ['object'] and schema_properties: fields += [ Field(name=key, required=key in schema_required) for key in schema_properties.keys() ] if rel == 'self': rel = 'read' content[rel] = Link(url=url, action=method, fields=fields) return content
def get_example_uri(path): """Returns an example URI for a path template Args: path (openapi.Path): path object for a specific resource Returns: str: The path with concrete path parameters. """ params = {} for variable in uritemplate.variables(path): params[variable] = '1' return uritemplate.expand(path, **params)
def rewrite_uritemplate_with_regexps(url_path: str, methods: Iterable[ComponentMethod]) -> str: for variable_name in uritemplate.variables(url_path): arguments = (method.get_argument(variable_name) for method in methods) argument_types = {argument.type_ for argument in arguments if argument is not None} if len(argument_types) > 1: raise Exception( f'Different methods are bound to the same path variable, ' f'but have different types annotated: {argument_types}', ) regexp = get_regexp(*argument_types) url_path = url_path.replace(f'{{{variable_name}}}', f'(?P<{variable_name}>{regexp})') return url_path
def get_path_fields(self, path, method, view): """ Return a list of `coreapi.Field` instances corresponding to any templated path variables. """ model = getattr(getattr(view, 'queryset', None), 'model', None) fields = [] for variable in uritemplate.variables(path): if variable == 'version': continue title = '' description = '' schema_cls = coreschema.String kwargs = {} if model is not None: # Attempt to infer a field description if possible. try: model_field = model._meta.get_field(variable) except: model_field = None if model_field is not None and hasattr(model_field, 'verbose_name'): title = force_text(model_field.verbose_name) if model_field is not None and hasattr(model_field, 'help_text'): description = force_text(model_field.help_text) elif model_field is not None and hasattr( model_field, 'primary_key'): description = get_pk_description(model, model_field) if hasattr(view, 'lookup_value_regex' ) and view.lookup_field == variable: kwargs['pattern'] = view.lookup_value_regex elif isinstance(model_field, models.AutoField): schema_cls = coreschema.Integer field = Field(name=variable, location='path', required=True, schema=schema_cls(title=title, description=description, **kwargs)) fields.append(field) return fields
def get_link(url, method, func): """ Returns a CoreAPI `Link` object for a given view function. """ path_params = uritemplate.variables(url) spec = getargspec(func) names = spec.args num_optional = len(spec.defaults or []) num_required = len(names) - num_optional required_list = [True for idx in range(num_required) ] + [False for idx in range(num_optional)] default_location = 'query' if method in ('GET', 'DELETE') else 'form' locations = [ 'path' if (name in path_params) else default_location for name in names ] link_description = '' field_descriptions = ['' for name in names] if func.__doc__: docstring = dedent(func.__doc__) else: docstring = '' for line in docstring.splitlines(): if line.startswith('* '): field_name, desc = line.split('-', 1) field_descriptions.append(desc.strip()) else: link_description += line + '\n' link_description = link_description.strip() fields = [ coreapi.Field(name=name, required=required, location=location, description=description) for name, required, location, description in zip( names, required_list, locations, field_descriptions) ] return coreapi.Link(url, action=method, fields=fields, description=link_description)
def get_path_parameters(self, path, view_cls): """Return a list of Parameter instances corresponding to any templated path variables. :param str path: templated request path :param type view_cls: the view class associated with the path :return: path parameters :rtype: list[openapi.Parameter] """ parameters = [] model = getattr(getattr(view_cls, 'queryset', None), 'model', None) for variable in uritemplate.variables(path): pattern = None type = openapi.TYPE_STRING description = None if model is not None: # Attempt to infer a field description if possible. try: model_field = model._meta.get_field(variable) except Exception: # pragma: no cover model_field = None if model_field is not None and model_field.help_text: description = force_text(model_field.help_text) elif model_field is not None and model_field.primary_key: description = get_pk_description(model, model_field) if hasattr(view_cls, 'lookup_value_regex') and getattr( view_cls, 'lookup_field', None) == variable: pattern = view_cls.lookup_value_regex elif isinstance(model_field, django.db.models.AutoField): type = openapi.TYPE_INTEGER field = openapi.Parameter( name=variable, required=True, in_=openapi.IN_PATH, type=type, pattern=pattern, description=description, ) parameters.append(field) return parameters
def link_uritemplate_param_declared(link): params = uritemplate.variables(link.path.template) for param in params: if link.schema.typestr != 'object': msg = ("The resource '{0}' is not an object, " "so the parameter '{1}' in the uritemplate " "'{2}' is not declared in link '{3}'") raise ValidationFail( msg.format(link.schema.fullname(), param, link.path.template, link.name), link) elif param not in link.schema.properties: msg = ("The parameter '{0}' in the uritemplate '{1}'" " in link '{2}' is not declared in properties" " in resouce '{3}'") raise ValidationFail( msg.format(param, link.path.template, link.name, link.schema.fullname()), link)
def _validate(self): # Check variable names are consistent declared_names = set([col.name for col in self._columns.values()]) used_names: Set[str] = set() for name_set in (variables(uri) for column in self._columns.values() for uri in [column.propertyUrl, column.valueUrl] if uri is not None): used_names.update(name_set) if not declared_names.issuperset(used_names): logging.error( f"Unmatched variable names: {used_names.difference(declared_names)}" ) # Check used prefixes used_prefixes = set( t.split(':')[0] for column in self._columns.values() for t in [column.propertyUrl, column.valueUrl] if t is not None and not t.startswith('http') and ':' in t) if not set(prefix_map.keys()).issuperset(used_prefixes): logging.error( f"Unknown prefixes used: {used_prefixes.difference(prefix_map.keys())}" )
def get_path_parameters(self, path, view_cls): # Get from serializer, not model parameters = [] for variable in sorted(uritemplate.variables(path)): if view_cls.serializer_class: serializer = view_cls.serializer_class() serializer_field = serializer.fields[variable] attrs = get_basic_type_info(serializer_field) or { "type": openapi.TYPE_STRING } description = getattr(serializer_field, "help_text") title = getattr(serializer_field, "label") field = openapi.Parameter( name=variable, title=utils.force_real_str(title), description=utils.force_real_str(description), required=True, in_=openapi.IN_PATH, **attrs, ) parameters.append(field) return parameters
def rel(self, name, **kwargs): link = self.schema.get_link(name) method = link.get('method', 'get') href = link.get('href', '') params = kwargs.get('params', {}) variables = uritemplate.variables(href) uri = self.expand_uri(name, **params) if not urlparse.urlparse(uri).netloc: uri = urlparse.urljoin(self.url, uri) if 'params' in kwargs: unused_params = { k: v for k, v in params.items() if k not in variables } kwargs['params'] = unused_params return self.session.resource(uri, method=method, **kwargs)
def variables(self): """Returns the variables the URI takes""" return uritemplate.variables(self.url)
def get_path_variables(self) -> Set[str]: return uritemplate.variables(self.url_path)
def test_reserved(self): template = 'http://example.com/{+x,y}/{+z}' vars = uritemplate.variables(template) self.assertEquals(vars, set(['x', 'y', 'z']))
def test_variables(self): self.assertEqual(variables(self.uri), URITemplate(self.uri).variable_names)
def valueUrl(self): url = self.schema.get('valueUrl') if url and variables(url) == {self.key}: return expand(url, {self.key: self.value})
def test_consumers_only_needs_bitbucket_url_and_username(self): assert set(['username', 'bitbucket_url']) == \ variables(self._consumers)
def path_variables(self): return uritemplate.variables(self.url_path)
def bad_params(template, var_dict): """Returns dictionary of parameters that do not pass validation. """ temp_vars = variables(template) return var_dict.keys() - temp_vars
def test_query(self): template = 'http://example.com{?x,y,z}' vars = uritemplate.variables(template) self.assertEquals(vars, set(['x', 'y', 'z']))
def test_parameter(self): template = 'http://example.com{;x,y}{;z}' vars = uritemplate.variables(template) self.assertEquals(vars, set(['x', 'y', 'z']))
def test_query_continuation(self): template = 'http://example.com?a=1&b=2{&x,y}&r=13{&z}' vars = uritemplate.variables(template) self.assertEquals(vars, set(['x', 'y', 'z']))
def test_simple(self): template = 'http://example.com/{x,y}' vars = uritemplate.variables(template) self.assertEquals(vars, set(['x', 'y']))
def test_overlapping_expansion(self): template = 'http://{a,b}.com{;a,b}{/a,b}/page{?a,b}{&a,b}{#a,b}' vars = uritemplate.variables(template) self.assertEquals(vars, set(['a', 'b']))
def test_explode_modifier(self): template = 'http://example.com{/x*,y*}/page{/z*}' vars = uritemplate.variables(template) self.assertEquals(vars, set(['x', 'y', 'z']))
from csv import DictReader from gssutils import pathify import uritemplate import json column_titles = {} columns_names = set() with open('columns.csv') as columns_file: for row in DictReader(columns_file): column_titles[row['title']] = row columns_names.add(row['name']) for col in column_titles.values(): if col['value_template'] != '': vars = set(uritemplate.variables(col['value_template'])) assert vars.issubset(columns_names) codelists_metadata = json.load(open('codelists-metadata.json')) codelists = [(table['url'], table['rdfs:label']) for table in codelists_metadata['tables']] codelist_uris = [ f"http://gss-data.org.uk/def/concept-scheme/{pathify(label)}" for (file, label) in codelists ] component_labels = {} with open('components.csv') as components_file: for row in DictReader(components_file): component_labels[row['Label']] = row if row['Component Type'] == 'Measure':
def test_path_segment(self): template = 'http://example.com{/x,y}/w{/z}' vars = uritemplate.variables(template) self.assertEquals(vars, set(['x', 'y', 'z']))
def test_prefix_modifier(self): template = 'http://example.com{/x:5,y:7}{/z:2}' vars = uritemplate.variables(template) self.assertEquals(vars, set(['x', 'y', 'z']))
def test_label(self): template = 'http://{.x,y,z}' vars = uritemplate.variables(template) self.assertEquals(vars, set(['x', 'y', 'z']))
def test_fragment(self): template = 'http://example.com/{#x,y},{#z}' vars = uritemplate.variables(template) self.assertEquals(vars, set(['x', 'y', 'z']))
def test_partially_overlapping(self): template = 'http://{.a,b}{/b,c}/{c,d}' vars = uritemplate.variables(template) self.assertEquals(vars, set(['a', 'b', 'c', 'd']))
def test_mixed_expansion_types(self): template = 'http://{a,b}.com{;c,d}{/e,f}/page{?g,h}{&i,j}{#k,l}' vars = uritemplate.variables(template) expected_vars = set('abcdefghijkl') self.assertEquals(vars, expected_vars)