Coverage for /builds/ase/ase/ase/db/project.py: 97.87%
47 statements
« prev ^ index » next coverage.py v7.5.3, created at 2025-08-02 00:12 +0000
« prev ^ index » next coverage.py v7.5.3, created at 2025-08-02 00:12 +0000
1# fmt: off
3from pathlib import Path
5from ase.db.core import KeyDescription
6from ase.db.row import row2dct
7from ase.formula import Formula
10class DatabaseProject:
11 """Settings for web view of a database.
13 For historical reasons called a "Project".
14 """
15 _ase_templates = Path('ase/db/templates')
17 def __init__(self, name, title, *,
18 key_descriptions,
19 database,
20 default_columns):
21 self.name = name
22 self.title = title
23 self.uid_key = 'id'
25 # The templates loop over "key descriptions" when they want to
26 # loop over keys.
27 #
28 # Therefore, any key without description will not be rendered.
29 # Therefore, we need to make dummy key descriptions of everything
30 # in the database, ensuring that all keys are visible.
32 all_keys = database.get_all_key_names()
34 key_descriptions = {
35 **{key: KeyDescription(key) for key in all_keys},
36 **key_descriptions}
38 for key, value in key_descriptions.items():
39 assert isinstance(key, str), type(key)
40 assert isinstance(value, KeyDescription), type(value)
42 self.key_descriptions = key_descriptions
43 self.database = database
44 self.default_columns = default_columns
46 def get_search_template(self):
47 return self._ase_templates / 'search.html'
49 def get_row_template(self):
50 return self._ase_templates / 'row.html'
52 def get_table_template(self):
53 return self._ase_templates / 'table.html'
55 def handle_query(self, args) -> str:
56 """Convert request args to ase.db query string."""
57 return args['query']
59 def row_to_dict(self, row):
60 """Convert row to dict for use in html template."""
61 dct = row2dct(row, self.key_descriptions)
62 dct['formula'] = Formula(row.formula).convert('abc').format('html')
63 return dct
65 def uid_to_row(self, uid):
66 return self.database.get(f'{self.uid_key}={uid}')
68 @classmethod
69 def dummyproject(cls, **kwargs):
70 class DummyDatabase:
71 def select(self, *args, **kwargs):
72 return iter([])
74 def get_all_key_names(self):
75 return set()
77 _kwargs = dict(
78 name='test',
79 title='test',
80 key_descriptions={},
81 database=DummyDatabase(), # XXX
82 default_columns=[])
83 _kwargs.update(kwargs)
84 return cls(**_kwargs)
86 # If we make this a classmethod, and try to instantiate the class,
87 # it would fail on subclasses. So we use staticmethod
88 @staticmethod
89 def load_db_as_ase_project(name, database):
90 from ase.db.core import get_key_descriptions
91 from ase.db.table import all_columns
93 return DatabaseProject(
94 name=name,
95 title=database.metadata.get('title', ''),
96 key_descriptions=get_key_descriptions(),
97 database=database,
98 default_columns=all_columns)