Skip to content

Commit

Permalink
Add generator of full available node namespace
Browse files Browse the repository at this point in the history
A utility `aiida.restapi.common.identifiers.get_node_namespace` is added
that constructs the full nested node namespace present in the current
database. Each entry will contain a `full_type` attribute, which
uniquely identify the exact type, in the case of a leaf, or the sub
class of node types in the case of a namespace. The `full_type` can be
used to generate the query builder filters that will allow to query
exactly for this node type or its sub classes. This is stored in the
REST API module because it is exposed as an endpoint. This can then be
consumed by the Materials Cloud to dynamically build up an index of
available node classes with their `full_types` which can be used to
query for them.
  • Loading branch information
sphuber committed Oct 25, 2019
1 parent 3e70750 commit e3219cf
Show file tree
Hide file tree
Showing 4 changed files with 461 additions and 0 deletions.
1 change: 1 addition & 0 deletions aiida/backends/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@
'plugins.factories': ['aiida.backends.tests.plugins.test_factories'],
'plugins.utils': ['aiida.backends.tests.plugins.test_utils'],
'query': ['aiida.backends.tests.test_query'],
'restapi.identifiers': ['aiida.backends.tests.restapi.test_identifiers'],
'restapi': ['aiida.backends.tests.test_restapi'],
'tools.data.orbital': ['aiida.backends.tests.tools.data.orbital.test_orbitals'],
'tools.importexport.common.archive': ['aiida.backends.tests.tools.importexport.common.test_archive'],
Expand Down
Empty file.
82 changes: 82 additions & 0 deletions aiida/backends/tests/restapi/test_identifiers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# -*- coding: utf-8 -*-
###########################################################################
# Copyright (c), The AiiDA team. All rights reserved. #
# This file is part of the AiiDA code. #
# #
# The code is hosted on GitHub at https://github.com/aiidateam/aiida-core #
# For further information on the license, see the LICENSE.txt file #
# For further information please visit http://www.aiida.net #
###########################################################################
"""Tests for the `aiida.restapi.common.identifiers` module."""
from __future__ import absolute_import
from aiida.backends.testbase import AiidaTestCase
from aiida.restapi.common.identifiers import get_full_type_filters, FULL_TYPE_CONCATENATOR, LIKE_OPERATOR_CHARACTER


class TestIdentifiers(AiidaTestCase):
"""Tests for the :py:mod:`~aiida.restapi.common.identifiers` module."""

def test_get_full_type_filters(self):
"""Test the `get_full_type_filters` function."""

with self.assertRaises(TypeError):
get_full_type_filters(10)

with self.assertRaises(ValueError):
get_full_type_filters('string_without_full_type_concatenator')

with self.assertRaises(ValueError):
get_full_type_filters(
'too_many_{like}{like}{concat}process_type'.format(
like=LIKE_OPERATOR_CHARACTER, concat=FULL_TYPE_CONCATENATOR
)
)

with self.assertRaises(ValueError):
get_full_type_filters(
'node_type{concat}too_many_{like}{like}'.format(
like=LIKE_OPERATOR_CHARACTER, concat=FULL_TYPE_CONCATENATOR
)
)

with self.assertRaises(ValueError):
get_full_type_filters(
'not_at_{like}_the_end{concat}process_type'.format(
like=LIKE_OPERATOR_CHARACTER, concat=FULL_TYPE_CONCATENATOR
)
)

with self.assertRaises(ValueError):
get_full_type_filters(
'node_type{concat}not_at_{like}_the_end'.format(
like=LIKE_OPERATOR_CHARACTER, concat=FULL_TYPE_CONCATENATOR
)
)

# Equals on both
filters = get_full_type_filters('node_type{concat}process_type'.format(concat=FULL_TYPE_CONCATENATOR))
self.assertEqual(filters['node_type'], 'node\\_type')
self.assertEqual(filters['process_type'], 'process\\_type')

# Like on `node_type`
filters = get_full_type_filters(
'node_type{like}{concat}process_type'.format(like=LIKE_OPERATOR_CHARACTER, concat=FULL_TYPE_CONCATENATOR)
)
self.assertEqual(filters['node_type'], {'like': 'node\\_type%'})
self.assertEqual(filters['process_type'], 'process\\_type')

# Like on `process_type`
filters = get_full_type_filters(
'node_type{concat}process_type{like}'.format(like=LIKE_OPERATOR_CHARACTER, concat=FULL_TYPE_CONCATENATOR)
)
self.assertEqual(filters['node_type'], 'node\\_type')
self.assertEqual(filters['process_type'], {'like': 'process\\_type%'})

# Like on both
filters = get_full_type_filters(
'node_type{like}{concat}process_type{like}'.format(
like=LIKE_OPERATOR_CHARACTER, concat=FULL_TYPE_CONCATENATOR
)
)
self.assertEqual(filters['node_type'], {'like': 'node\\_type%'})
self.assertEqual(filters['process_type'], {'like': 'process\\_type%'})
Loading

0 comments on commit e3219cf

Please sign in to comment.