optimade 2.0.3 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "extends": [
3
+ "eslint:recommended",
4
+ "plugin:@typescript-eslint/recommended"
5
+ ],
6
+ "plugins": [
7
+ "@typescript-eslint"
8
+ ],
9
+ "parser": "@typescript-eslint/parser",
10
+ "root": true,
11
+ "env": {
12
+ "node": true
13
+ },
14
+ "rules": {
15
+ "@typescript-eslint/no-explicit-any": "off"
16
+ }
17
+ }
package/README.md CHANGED
@@ -57,10 +57,10 @@ const providersMap = await optimadeClient.getProviders(); // { [id: string]: Pro
57
57
 
58
58
  const providerIds = Object.keys(providersMap); // string[]
59
59
 
60
- const results = await optimadeClient.getStructuresAll(
61
- providerIds,
62
- YOUR_OPTIMADE_QUERY,
63
- ); // [StructuresResponse[], Provider][]
60
+ const results = await optimadeClient.getStructuresAll({
61
+ providers: Provider[],
62
+ filter: YOUR_OPTIMADE_QUERY,
63
+ }); // [StructuresResponse[], Provider][]
64
64
  ```
65
65
 
66
66
  Importing depends on your environment. See also the `examples` folder. The
@@ -79,12 +79,14 @@ const optimadeClient = new Optimade({
79
79
  optimadeClient.providers = prefetched.providers;
80
80
  optimadeClient.apis = prefetched.apis;
81
81
 
82
- const results = await optimadeClient.getStructuresAll(
83
- providerIds,
84
- YOUR_OPTIMADE_QUERY,
82
+ const results = await optimadeClient.getStructuresAll({
83
+ providers: Provider[],
84
+ filter: YOUR_OPTIMADE_QUERY,
85
85
  page: number,
86
- limit: number
87
- ); // [StructuresResponse[], Provider][]
86
+ limit: number,
87
+ offset: number,
88
+ batch: true
89
+ }); // [StructuresResponse[], Provider][]
88
90
  ```
89
91
 
90
92
  See also the `demo` folder.
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('isomorphic-unfetch')) :
3
3
  typeof define === 'function' && define.amd ? define(['exports', 'isomorphic-unfetch'], factory) :
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.optimade = {}));
5
- }(this, (function (exports) { 'use strict';
5
+ })(this, (function (exports) { 'use strict';
6
6
 
7
7
  function allSettled(promises, catcher = () => null) {
8
8
  return Promise.all(promises.map(promise => promise.catch(catcher)));
@@ -25,34 +25,86 @@
25
25
  }
26
26
  }
27
27
 
28
+ var version = "2.1.0";
29
+
28
30
  class Optimade {
31
+ providersUrl = '';
32
+ corsProxyUrl = '';
33
+ providers = null;
34
+ apis = {};
35
+ reqStack = [];
29
36
  constructor({ providersUrl = '', corsProxyUrl = '' } = {}) {
30
- this.providersUrl = '';
31
- this.corsProxyUrl = '';
32
- this.providers = null;
33
- this.apis = {};
34
- this.reqStack = [];
35
37
  this.corsProxyUrl = corsProxyUrl;
36
38
  this.providersUrl = this.wrapUrl(providersUrl);
37
39
  }
40
+ async addProvider(provider) {
41
+ if (!this.apis[provider.id]) {
42
+ this.apis[provider.id] = [];
43
+ }
44
+ try {
45
+ const ver = provider.attributes
46
+ && provider.attributes.api_version ?
47
+ provider.attributes.api_version.charAt(0) : '';
48
+ const api = await this.getApis(provider, ver ? `v${ver}` : '');
49
+ if (api.attributes.available_endpoints.includes('structures')) {
50
+ this.apis[provider.id].push(api);
51
+ }
52
+ }
53
+ catch (ignore) {
54
+ console.log(ignore);
55
+ }
56
+ if (!provider.attributes.query_limits) {
57
+ const formula = `chemical_formula_anonymous="A2B"`;
58
+ const url = `${provider.attributes.base_url}/v1/structures?filter=${formula}&page_limit=1000`;
59
+ try {
60
+ const res = await fetch(url).then(res => res.json());
61
+ const version = res.meta && res.meta.api_version || this.apis[provider.id][0].attributes.api_version;
62
+ const detail = (errors) => {
63
+ return errors
64
+ ? errors.length
65
+ ? errors[0].detail
66
+ : errors.detail
67
+ : '10';
68
+ };
69
+ const limits = detail(res.errors)
70
+ .match(/\d+/g)
71
+ .filter((number) => +number < 1000)
72
+ .map((number) => +number);
73
+ provider.attributes = {
74
+ ...provider.attributes,
75
+ api_version: version,
76
+ query_limits: limits
77
+ };
78
+ }
79
+ catch (error) {
80
+ console.log(error);
81
+ }
82
+ }
83
+ this.providers[provider.id] = provider;
84
+ return this.providers;
85
+ }
38
86
  async getProviders(api) {
39
87
  const providers = await (api ?
40
88
  this.followLinks(api).catch(() => null) :
41
89
  Optimade.getJSON(this.providersUrl).catch(() => null));
42
- if (!providers)
90
+ if (!providers) {
43
91
  return null;
44
- if (!this.providers)
92
+ }
93
+ if (!this.providers) {
45
94
  this.providers = {};
95
+ }
46
96
  const data = providers.data.filter(Optimade.isProviderValid);
47
97
  const ver = providers.meta && providers.meta.api_version ?
48
98
  providers.meta.api_version.charAt(0) : '';
49
99
  for (const provider of data) {
50
- if (!this.apis[provider.id])
100
+ if (!this.apis[provider.id]) {
51
101
  this.apis[provider.id] = [];
102
+ }
52
103
  try {
53
104
  const api = await this.getApis(provider, ver ? `v${ver}` : '');
54
- if (!api)
105
+ if (!api) {
55
106
  continue;
107
+ }
56
108
  if (api.attributes.available_endpoints.includes('structures')) {
57
109
  this.apis[provider.id].push(api);
58
110
  if (!this.providers[provider.id]) {
@@ -63,7 +115,9 @@
63
115
  await this.getProviders(api);
64
116
  }
65
117
  }
66
- catch (ignore) { }
118
+ catch (ignore) {
119
+ console.log(ignore);
120
+ }
67
121
  }
68
122
  return this.providers;
69
123
  }
@@ -71,25 +125,26 @@
71
125
  if (typeof provider === 'string') {
72
126
  provider = this.providers[provider];
73
127
  }
74
- if (!provider)
128
+ if (!provider) {
75
129
  throw new Error('No provider found');
130
+ }
76
131
  const url = this.wrapUrl(`${provider.attributes.base_url}/${version}`, '/info');
77
- if (this.isDuplicatedReq(url))
132
+ if (this.isDuplicatedReq(url)) {
78
133
  return null;
134
+ }
79
135
  const apis = await Optimade.getJSON(url);
80
136
  return Optimade.apiVersion(apis);
81
137
  }
82
- async getStructures(providerId, filter = '', page = 1, limit) {
83
- if (!this.apis[providerId])
138
+ async getStructures({ providerId, filter, page, limit, offset }) {
139
+ if (!this.apis[providerId]) {
84
140
  return null;
141
+ }
85
142
  const apis = this.apis[providerId].filter(api => api.attributes.available_endpoints.includes('structures'));
86
143
  const provider = this.providers[providerId];
87
144
  const structures = await allSettled(apis.map(async (api) => {
88
- if (page <= 0)
89
- page = 1;
90
145
  const pageLimit = limit ? `&page_limit=${limit}` : '';
91
- const pageNumber = page ? `&page_number=${page - 1}` : '';
92
- const pageOffset = limit && page ? `&page_offset=${limit * (page - 1)}` : '';
146
+ const pageNumber = page ? `&page_number=${page}` : '';
147
+ const pageOffset = offset ? `&page_offset=${offset}` : '';
93
148
  const params = filter ? `${pageLimit + pageNumber + pageOffset}` : `?${pageLimit}`;
94
149
  const url = this.wrapUrl(Optimade.apiVersionUrl(api), filter ? `/structures?filter=${filter + params}` : `/structures${params}`);
95
150
  try {
@@ -106,17 +161,17 @@
106
161
  }
107
162
  else {
108
163
  structure.meta.pages = Math.ceil(structure.meta.data_returned / (limit || structure.data.length));
109
- structure.meta.limits = provider.attributes.query_limits;
164
+ structure.meta.limits = provider.attributes.query_limits || [10];
110
165
  return structures.concat(structure);
111
166
  }
112
167
  }, []);
113
168
  }
114
- getStructuresAll(providerIds, filter = '', page = 0, limit, batch = true) {
115
- const results = providerIds.reduce((structures, providerId) => {
169
+ getStructuresAll({ providers, filter, page, limit, offset, batch = true }) {
170
+ const results = providers.reduce((structures, providerId) => {
116
171
  const provider = this.providers[providerId];
117
172
  if (provider) {
118
173
  structures.push(allSettled([
119
- this.getStructures(providerId, filter, page, limit),
174
+ this.getStructures({ providerId, filter, page, limit, offset }),
120
175
  Promise.resolve(provider)
121
176
  ]));
122
177
  }
@@ -125,8 +180,9 @@
125
180
  return batch ? Promise.all(results) : results;
126
181
  }
127
182
  async followLinks(api) {
128
- if (!api.attributes.available_endpoints.includes('links'))
183
+ if (!api.attributes.available_endpoints.includes('links')) {
129
184
  return null;
185
+ }
130
186
  const url = this.wrapUrl(Optimade.apiVersionUrl(api), '/links');
131
187
  return !this.isDuplicatedReq(url) ? Optimade.getJSON(url) : null;
132
188
  }
@@ -143,6 +199,7 @@
143
199
  if (params) {
144
200
  Object.entries(params).forEach((param) => url.searchParams.append(...param));
145
201
  }
202
+ Object.assign(headers, { 'User-Agent': `tilde-lab-optimade-client/${version}` });
146
203
  const res = await fetchWithTimeout(url.toString(), { headers }, timeout);
147
204
  if (!res.ok) {
148
205
  const err = await res.json();
@@ -176,4 +233,4 @@
176
233
 
177
234
  Object.defineProperty(exports, '__esModule', { value: true });
178
235
 
179
- })));
236
+ }));
package/dist/index.mjs CHANGED
@@ -21,34 +21,86 @@ async function fetchWithTimeout(url, options = {}, timeout = 5000) {
21
21
  }
22
22
  }
23
23
 
24
+ var version = "2.1.0";
25
+
24
26
  class Optimade {
27
+ providersUrl = '';
28
+ corsProxyUrl = '';
29
+ providers = null;
30
+ apis = {};
31
+ reqStack = [];
25
32
  constructor({ providersUrl = '', corsProxyUrl = '' } = {}) {
26
- this.providersUrl = '';
27
- this.corsProxyUrl = '';
28
- this.providers = null;
29
- this.apis = {};
30
- this.reqStack = [];
31
33
  this.corsProxyUrl = corsProxyUrl;
32
34
  this.providersUrl = this.wrapUrl(providersUrl);
33
35
  }
36
+ async addProvider(provider) {
37
+ if (!this.apis[provider.id]) {
38
+ this.apis[provider.id] = [];
39
+ }
40
+ try {
41
+ const ver = provider.attributes
42
+ && provider.attributes.api_version ?
43
+ provider.attributes.api_version.charAt(0) : '';
44
+ const api = await this.getApis(provider, ver ? `v${ver}` : '');
45
+ if (api.attributes.available_endpoints.includes('structures')) {
46
+ this.apis[provider.id].push(api);
47
+ }
48
+ }
49
+ catch (ignore) {
50
+ console.log(ignore);
51
+ }
52
+ if (!provider.attributes.query_limits) {
53
+ const formula = `chemical_formula_anonymous="A2B"`;
54
+ const url = `${provider.attributes.base_url}/v1/structures?filter=${formula}&page_limit=1000`;
55
+ try {
56
+ const res = await fetch(url).then(res => res.json());
57
+ const version = res.meta && res.meta.api_version || this.apis[provider.id][0].attributes.api_version;
58
+ const detail = (errors) => {
59
+ return errors
60
+ ? errors.length
61
+ ? errors[0].detail
62
+ : errors.detail
63
+ : '10';
64
+ };
65
+ const limits = detail(res.errors)
66
+ .match(/\d+/g)
67
+ .filter((number) => +number < 1000)
68
+ .map((number) => +number);
69
+ provider.attributes = {
70
+ ...provider.attributes,
71
+ api_version: version,
72
+ query_limits: limits
73
+ };
74
+ }
75
+ catch (error) {
76
+ console.log(error);
77
+ }
78
+ }
79
+ this.providers[provider.id] = provider;
80
+ return this.providers;
81
+ }
34
82
  async getProviders(api) {
35
83
  const providers = await (api ?
36
84
  this.followLinks(api).catch(() => null) :
37
85
  Optimade.getJSON(this.providersUrl).catch(() => null));
38
- if (!providers)
86
+ if (!providers) {
39
87
  return null;
40
- if (!this.providers)
88
+ }
89
+ if (!this.providers) {
41
90
  this.providers = {};
91
+ }
42
92
  const data = providers.data.filter(Optimade.isProviderValid);
43
93
  const ver = providers.meta && providers.meta.api_version ?
44
94
  providers.meta.api_version.charAt(0) : '';
45
95
  for (const provider of data) {
46
- if (!this.apis[provider.id])
96
+ if (!this.apis[provider.id]) {
47
97
  this.apis[provider.id] = [];
98
+ }
48
99
  try {
49
100
  const api = await this.getApis(provider, ver ? `v${ver}` : '');
50
- if (!api)
101
+ if (!api) {
51
102
  continue;
103
+ }
52
104
  if (api.attributes.available_endpoints.includes('structures')) {
53
105
  this.apis[provider.id].push(api);
54
106
  if (!this.providers[provider.id]) {
@@ -59,7 +111,9 @@ class Optimade {
59
111
  await this.getProviders(api);
60
112
  }
61
113
  }
62
- catch (ignore) { }
114
+ catch (ignore) {
115
+ console.log(ignore);
116
+ }
63
117
  }
64
118
  return this.providers;
65
119
  }
@@ -67,25 +121,26 @@ class Optimade {
67
121
  if (typeof provider === 'string') {
68
122
  provider = this.providers[provider];
69
123
  }
70
- if (!provider)
124
+ if (!provider) {
71
125
  throw new Error('No provider found');
126
+ }
72
127
  const url = this.wrapUrl(`${provider.attributes.base_url}/${version}`, '/info');
73
- if (this.isDuplicatedReq(url))
128
+ if (this.isDuplicatedReq(url)) {
74
129
  return null;
130
+ }
75
131
  const apis = await Optimade.getJSON(url);
76
132
  return Optimade.apiVersion(apis);
77
133
  }
78
- async getStructures(providerId, filter = '', page = 1, limit) {
79
- if (!this.apis[providerId])
134
+ async getStructures({ providerId, filter, page, limit, offset }) {
135
+ if (!this.apis[providerId]) {
80
136
  return null;
137
+ }
81
138
  const apis = this.apis[providerId].filter(api => api.attributes.available_endpoints.includes('structures'));
82
139
  const provider = this.providers[providerId];
83
140
  const structures = await allSettled(apis.map(async (api) => {
84
- if (page <= 0)
85
- page = 1;
86
141
  const pageLimit = limit ? `&page_limit=${limit}` : '';
87
- const pageNumber = page ? `&page_number=${page - 1}` : '';
88
- const pageOffset = limit && page ? `&page_offset=${limit * (page - 1)}` : '';
142
+ const pageNumber = page ? `&page_number=${page}` : '';
143
+ const pageOffset = offset ? `&page_offset=${offset}` : '';
89
144
  const params = filter ? `${pageLimit + pageNumber + pageOffset}` : `?${pageLimit}`;
90
145
  const url = this.wrapUrl(Optimade.apiVersionUrl(api), filter ? `/structures?filter=${filter + params}` : `/structures${params}`);
91
146
  try {
@@ -102,17 +157,17 @@ class Optimade {
102
157
  }
103
158
  else {
104
159
  structure.meta.pages = Math.ceil(structure.meta.data_returned / (limit || structure.data.length));
105
- structure.meta.limits = provider.attributes.query_limits;
160
+ structure.meta.limits = provider.attributes.query_limits || [10];
106
161
  return structures.concat(structure);
107
162
  }
108
163
  }, []);
109
164
  }
110
- getStructuresAll(providerIds, filter = '', page = 0, limit, batch = true) {
111
- const results = providerIds.reduce((structures, providerId) => {
165
+ getStructuresAll({ providers, filter, page, limit, offset, batch = true }) {
166
+ const results = providers.reduce((structures, providerId) => {
112
167
  const provider = this.providers[providerId];
113
168
  if (provider) {
114
169
  structures.push(allSettled([
115
- this.getStructures(providerId, filter, page, limit),
170
+ this.getStructures({ providerId, filter, page, limit, offset }),
116
171
  Promise.resolve(provider)
117
172
  ]));
118
173
  }
@@ -121,8 +176,9 @@ class Optimade {
121
176
  return batch ? Promise.all(results) : results;
122
177
  }
123
178
  async followLinks(api) {
124
- if (!api.attributes.available_endpoints.includes('links'))
179
+ if (!api.attributes.available_endpoints.includes('links')) {
125
180
  return null;
181
+ }
126
182
  const url = this.wrapUrl(Optimade.apiVersionUrl(api), '/links');
127
183
  return !this.isDuplicatedReq(url) ? Optimade.getJSON(url) : null;
128
184
  }
@@ -139,6 +195,7 @@ class Optimade {
139
195
  if (params) {
140
196
  Object.entries(params).forEach((param) => url.searchParams.append(...param));
141
197
  }
198
+ Object.assign(headers, { 'User-Agent': `tilde-lab-optimade-client/${version}` });
142
199
  const res = await fetchWithTimeout(url.toString(), { headers }, timeout);
143
200
  if (!res.ok) {
144
201
  const err = await res.json();
@@ -1 +1 @@
1
- {"providers":{"2dstructures":{"id":"2dstructures","type":"links","attributes":{"name":"2D Structures","description":"Two-dimensional (2D) materials from high-throughput computational exfoliation of experimentally known compounds.","base_url":"https://aiida.materialscloud.org/2dstructures/optimade","homepage":"https://materialscloud.org/explore/2dstructures","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"2dtopo":{"id":"2dtopo","type":"links","attributes":{"name":"2D topological insulators","description":"Quantum spin Hall insulator (QSHI) candidates through DFT band structure calculations of a database with 1825 compounds.","base_url":"https://aiida.materialscloud.org/2dtopo/optimade","homepage":"https://materialscloud.org/explore/2dtopo","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"cod":{"id":"cod","type":"links","attributes":{"name":"Crystallography Open Database","description":"Open-access collection of crystal structures of organic, inorganic, metal-organics compounds and minerals, excluding biopolymers","base_url":"https://www.crystallography.net/cod/optimade","homepage":"https://www.crystallography.net/cod","link_type":"child","query_limits":[10]}},"curated-cofs":{"id":"curated-cofs","type":"links","attributes":{"name":"CURATED covalent organic frameworks database","description":"Database of experimentally reported Covalent-Organic Frameworks (COFs), provided with DFT-optimized geometry and DDEC partial charges for molecular simulations.","base_url":"https://aiida.materialscloud.org/curated-cofs/optimade","homepage":"https://materialscloud.org/discover/curated-cofs","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"li-ion-conductors":{"id":"li-ion-conductors","type":"links","attributes":{"name":"Solid-state Li-ion conductors.","description":"High-throughput computational screening study for solid-state Li-ion conductors.","base_url":"https://aiida.materialscloud.org/li-ion-conductors/optimade","homepage":"https://materialscloud.org/explore/li-ion-conductors","link_type":"child","aggregate":"staging","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"mp":{"id":"mp","type":"links","attributes":{"name":"The Materials Project","description":"The Materials Project OPTIMADE endpoint","base_url":"https://optimade.materialsproject.org","homepage":"https://www.materialsproject.org","link_type":"child","api_version":"1.0.1","query_limits":[500]}},"mpds":{"id":"mpds","type":"links","attributes":{"name":"Materials Platform for Data Science","description":"A highly curated Pauling File dataset based on ~0.5M publications and backing up Springer Materials, ICDD PDF, ASM APD, MedeA, Pearson Crystal Data, AtomWork Advanced, etc.","base_url":"https://api.mpds.io","homepage":"https://mpds.io","link_type":"child","api_version":"1.0.0","query_limits":[10,100,750]}},"nmd":{"id":"nmd","type":"links","attributes":{"name":"novel materials discovery (NOMAD)","description":"A FAIR data sharing platform for materials science data","base_url":"https://nomad-lab.eu/prod/rae/optimade/","homepage":"https://nomad-lab.eu","link_type":"child","api_version":"1.0.1","query_limits":[500]}},"odbx":{"id":"odbx","type":"links","attributes":{"name":"odbx","description":"The Open Database of Xtals is run by the group of Dr Andrew Morris at the universities of Birmingham and Cambridge and is constructed using the matador library.","base_url":"https://optimade.odbx.science","homepage":"https://odbx.science","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[500]}},"optimade-sample":{"id":"optimade-sample","type":"links","attributes":{"name":"OPTIMADE Sample Database","description":"Database with example structures for OPTIMADE tests.","base_url":"https://aiida.materialscloud.org/optimade-sample/optimade","homepage":"https://materialscloud.org/explore/optimade-sample","link_type":"child","aggregate":"test","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"pyrene-mofs":{"id":"pyrene-mofs","type":"links","attributes":{"name":"Pyrene MOFs","description":"Pyrene Metal Organic Frameworks (MOFs).","base_url":"https://aiida.materialscloud.org/pyrene-mofs/optimade","homepage":"https://materialscloud.org/discover/pyrene-mofs","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"scdm":{"id":"scdm","type":"links","attributes":{"name":"Automated high-throughput Wannierisation","description":"Validation results of an automated protocol for generating maximally-localized Wannier functions in a high-throughput framework.","base_url":"https://aiida.materialscloud.org/autowannier/optimade","homepage":"https://materialscloud.org/explore/autowannier","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"sssp":{"id":"sssp","type":"links","attributes":{"name":"Standard solid-state pseudopotentials (SSSP)","description":"It contains data generated from the testing protocol of the standard solid-state pseudopotentials library.\n","base_url":"https://aiida.materialscloud.org/sssplibrary/optimade","homepage":"https://materialscloud.org/explore/sssplibrary","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"stoceriaitf":{"id":"stoceriaitf","type":"links","attributes":{"name":"SrTiO3-CeO2 interfaces","description":"Refining random structure searching results of SrTiO3-CeO2 interfaces, and exploring how it can affect ionic conduction. Candidate structures of the DFT validation calculations.","base_url":"https://aiida.materialscloud.org/stoceriaitf/optimade","homepage":"https://materialscloud.org/explore/stoceriaitf","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"tc-applicability":{"id":"tc-applicability","type":"links","attributes":{"name":"Applicability of tail-corrections in the molecular simulations of porous materials","description":"Tail-corrections in molecular simulations for adsorption of gasses in a diverse set of nanoporous crystalline materials (zeolites, Covalent Organic Framworks (COFs), and Metal Organic Frameworks (MOFs)).","base_url":"https://aiida.materialscloud.org/tc-applicability/optimade","homepage":"https://materialscloud.org/explore/tc-applicability","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"tcod":{"id":"tcod","type":"links","attributes":{"name":"Theoretical Crystallography Open Database","description":"Open-access collection of theoretically calculated or refined crystal structures of organic, inorganic, metal-organic compounds and minerals, excluding biopolymers","base_url":"https://www.crystallography.net/tcod/optimade","homepage":"https://www.crystallography.net/tcod","link_type":"child","query_limits":[10]}},"threedd":{"id":"threedd","type":"links","attributes":{"name":"Three-dimensional crystals database","description":"Curated set of relaxed three-dimensional crystal structures based on raw CIF data from the experimantal databases MPDS, COD, and ICSD.","base_url":"https://aiida.materialscloud.org/3dd/optimade","homepage":"https://materialscloud.org/explore/3dd","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"tin-antimony-sulfoiodide":{"id":"tin-antimony-sulfoiodide","type":"links","attributes":{"name":"Hidden spontaneous polarisation in the chalcohalide photovoltaic Sn2SbS2I3","description":"Structural, dynamic and electronic characterisation of a novel mixed-metal chalcohalide revealing hidden symmetry breaking and spontaneous polarisation.","base_url":"https://aiida.materialscloud.org/tin-antimony-sulfoiodide/optimade","homepage":"https://materialscloud.org/explore/tin-antimony-sulfoiodide","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"twodmatpedia":{"id":"twodmatpedia","type":"links","attributes":{"name":"2DMatpedia","description":"2DMatpedia, an open computational database of two-dimensional materials from top-down and bottom-up approaches","base_url":"http://optimade.2dmatpedia.org","homepage":"http://2dmatpedia.org","link_type":"child","api_version":"1.1.0","query_limits":[500]}}},"apis":{"2dstructures":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/2dstructures/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"2dtopo":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/2dtopo/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"aflow":[{"type":"info","id":"/","attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"http://aflow.org/API/optimade/v0.9/","version":"0.9.0"},{"url":"http://aflow.org/API/optimade/v1.0/","version":"1.0.0"},{"url":"http://aflow.org/API/optimade/v1.1/","version":"1.1.0"}],"formats":["json"],"entry_types_by_format":{"json":["structures","calculations"]},"available_endpoints":["structures","calculations","info","links"]},"is_index":false}],"cod":[{"attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"https://www.crystallography.net/cod/optimade/v1.0.0/","version":"1.0.0"}],"available_endpoints":["structures","info"],"entry_types_by_format":{"json":["structures"]},"formats":["json"]},"id":"/","type":"info"}],"curated-cofs":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/curated-cofs/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"jarvis":[{"type":"info","id":"/","attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"https://jarvis.nist.gov/optimade/jarvisdft/v1","version":"1.0.0"}],"formats":["json","xml","yaml"],"entry_types_by_format":{"json":["structures"],"xml":["structures"],"yaml":["structures"]},"available_endpoints":["structures","info","links","versions"],"is_index":false}}],"li-ion-conductors":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/li-ion-conductors/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"mp":[{"id":"/","type":"info","attributes":{"api_version":"1.0.1","available_api_versions":[{"url":"http://optimade.materialsproject.org/v1","version":"1.0.1"}],"formats":["json"],"available_endpoints":["info","links","structures","references"],"entry_types_by_format":{"json":["structures","references"]},"is_index":false}}],"mpds":[{"type":"info","attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"https://api.mpds.io/v1","version":"1.0.0"}],"available_endpoints":["structures","extensions/properties","extensions/phase_diagrams","extensions/phases"],"formats":["json"],"entry_types_by_format":{"json":["structures","extensions/properties","extensions/phase_diagrams","extensions/phases"]}}}],"nmd":[{"id":"/","type":"info","attributes":{"api_version":"1.0.1","available_api_versions":[{"url":"https://nomad-lab.eu/prod/rae/optimade/v1","version":"1.0.1"}],"formats":["json"],"available_endpoints":["info","links","structures","references"],"entry_types_by_format":{"json":["structures","references"]},"is_index":false}}],"odbx":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://optimade.odbx.science/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","structures","references"],"entry_types_by_format":{"json":["structures","references"]},"is_index":false}}],"omdb_production":[{"attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"http://optimade.openmaterialsdb.se/v1","version":"1.0.0"},{"url":"http://optimade.openmaterialsdb.se/v1.0.0","version":"1.0.0"},{"url":"http://optimade.openmaterialsdb.se/v1.0","version":"1.0.0"}],"available_endpoints":["info","links","structures"],"entry_types_by_format":{"json":["structures"]},"formats":["json"],"is_index":false},"id":"/","type":"info"}],"optimade-sample":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/optimade-sample/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"oqmd":[{"type":"info","id":"/","attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"http://oqmd.org/optimade/v1/","version":"1.0.0"}],"formats":["json","xml","yaml"],"entry_types_by_format":{"json":["structures"],"xml":["structures"],"yaml":["structures"]},"available_endpoints":["structures","info","links","versions"],"is_index":false}}],"pyrene-mofs":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/pyrene-mofs/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"scdm":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/autowannier/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"sssp":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/sssplibrary/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"stoceriaitf":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/stoceriaitf/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"tc-applicability":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/tc-applicability/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"tcod":[{"attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"https://www.crystallography.net/tcod/optimade/v1.0.0/","version":"1.0.0"}],"available_endpoints":["structures","info"],"entry_types_by_format":{"json":["structures"]},"formats":["json"]},"id":"/","type":"info"}],"threedd":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/3dd/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"tin-antimony-sulfoiodide":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/tin-antimony-sulfoiodide/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"twodmatpedia":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"http://optimade.2dmatpedia.org/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","structures","references"],"entry_types_by_format":{"json":["structures","references"]},"is_index":false}}]}}
1
+ {"providers":{"2dstructures":{"id":"2dstructures","type":"links","attributes":{"name":"2D Structures","description":"Two-dimensional (2D) materials from high-throughput computational exfoliation of experimentally known compounds.","base_url":"https://aiida.materialscloud.org/2dstructures/optimade","homepage":"https://materialscloud.org/explore/2dstructures","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"2dtopo":{"id":"2dtopo","type":"links","attributes":{"name":"2D topological insulators","description":"Quantum spin Hall insulator (QSHI) candidates through DFT band structure calculations.","base_url":"https://aiida.materialscloud.org/2dtopo/optimade","homepage":"https://materialscloud.org/explore/2dtopo","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"aflow":{"id":"aflow","type":"links","attributes":{"name":"AFLOW","description":"The AFLOW OPTIMADE endpoint","base_url":"http://aflow.org/API/optimade/","homepage":"http://aflow.org","link_type":"child","api_version":"1.0.0","query_limits":[10]}},"cod":{"id":"cod","type":"links","attributes":{"name":"Crystallography Open Database","description":"Open-access collection of crystal structures of organic, inorganic, metal-organics compounds and minerals, excluding biopolymers","base_url":"https://www.crystallography.net/cod/optimade","homepage":"https://www.crystallography.net/cod","link_type":"child","api_version":"1.1.0","query_limits":[100]}},"curated-cofs":{"id":"curated-cofs","type":"links","attributes":{"name":"CURATED covalent organic frameworks database","description":"Database of experimentally reported Covalent-Organic Frameworks (COFs), provided with DFT-optimized geometry and DDEC partial charges for molecular simulations.","base_url":"https://aiida.materialscloud.org/curated-cofs/optimade","homepage":"https://materialscloud.org/discover/curated-cofs","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"jarvis":{"id":"jarvis","type":"links","attributes":{"name":"JARVIS-DFT","description":"JARVIS-DFT is a materials property repository focused on density functional theory (DFT) predictions of material properties, especially for crystalline materials.","base_url":"https://jarvis.nist.gov/optimade/jarvisdft","homepage":"https://jarvis.nist.gov","link_type":"child","api_version":"1.1.0","query_limits":[10]}},"li-ion-conductors":{"id":"li-ion-conductors","type":"links","attributes":{"name":"Solid-state Li-ion conductors.","description":"High-throughput computational screening study for solid-state Li-ion conductors.","base_url":"https://aiida.materialscloud.org/li-ion-conductors/optimade","homepage":"https://materialscloud.org/explore/li-ion-conductors","link_type":"child","aggregate":"staging","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"mc3d-structures":{"id":"mc3d-structures","type":"links","attributes":{"name":"Materials Cloud three-dimensional crystals database (MC3D)","description":"Curated set of relaxed three-dimensional crystal structures based on raw CIF data from the experimantal databases MPDS, COD, and ICSD.","base_url":"https://aiida.materialscloud.org/mc3d-structures/optimade","homepage":"https://materialscloud.org/explore/mc3d-structures","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"mp":{"id":"mp","type":"links","attributes":{"name":"The Materials Project","description":"The Materials Project OPTIMADE endpoint","base_url":"https://optimade.materialsproject.org","homepage":"https://www.materialsproject.org","link_type":"child","api_version":"1.0.1","query_limits":[500]}},"mpds":{"id":"mpds","type":"links","attributes":{"name":"Materials Platform for Data Science","description":"A highly curated Pauling File dataset based on ~0.5M publications and backing up Springer Materials, ICDD PDF, ASM APD, MedeA, Pearson Crystal Data, AtomWork Advanced, etc.","base_url":"https://api.mpds.io","homepage":"https://mpds.io","link_type":"child","api_version":"1.0.0","query_limits":[5,10,100,750]}},"nmd":{"id":"nmd","type":"links","attributes":{"name":"novel materials discovery (NOMAD)","description":"A FAIR data sharing platform for materials science data","base_url":"https://nomad-lab.eu/prod/rae/optimade/","homepage":"https://nomad-lab.eu","link_type":"child","api_version":"1.0.1","query_limits":[500]}},"odbx":{"id":"odbx","type":"links","attributes":{"name":"odbx","description":"The Open Database of Xtals is run by the group of Dr Andrew Morris at the universities of Birmingham and Cambridge and is constructed using the matador library.","base_url":"https://optimade.odbx.science","homepage":"https://odbx.science","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[500]}},"omdb_production":{"id":"omdb_production","type":"links","attributes":{"name":"Open Materials Database (omdb) production database","description":"This is the main production version of the Open Materials Database","base_url":"http://optimade.openmaterialsdb.se","homepage":"http://openmaterialsdb.se","link_type":"child","api_version":"1.0.0","query_limits":[10]}},"optimade-sample":{"id":"optimade-sample","type":"links","attributes":{"name":"OPTIMADE Sample Database","description":"Database with example structures for OPTIMADE tests.","base_url":"https://aiida.materialscloud.org/optimade-sample/optimade","homepage":"https://materialscloud.org/explore/optimade-sample","link_type":"child","aggregate":"test","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"pyrene-mofs":{"id":"pyrene-mofs","type":"links","attributes":{"name":"Pyrene MOFs","description":"Pyrene Metal Organic Frameworks (MOFs).","base_url":"https://aiida.materialscloud.org/pyrene-mofs/optimade","homepage":"https://materialscloud.org/discover/pyrene-mofs","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"scdm":{"id":"scdm","type":"links","attributes":{"name":"Automated high-throughput Wannierisation","description":"Validation results of an automated protocol for generating maximally-localized Wannier functions in a high-throughput framework.","base_url":"https://aiida.materialscloud.org/autowannier/optimade","homepage":"https://materialscloud.org/explore/autowannier","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"sssp":{"id":"sssp","type":"links","attributes":{"name":"Standard solid-state pseudopotentials (SSSP)","description":"It contains data generated from the testing protocol of the standard solid-state pseudopotentials library.\n","base_url":"https://aiida.materialscloud.org/sssplibrary/optimade","homepage":"https://materialscloud.org/explore/sssplibrary","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"stoceriaitf":{"id":"stoceriaitf","type":"links","attributes":{"name":"SrTiO3-CeO2 interfaces","description":"Refining random structure searching results of SrTiO3-CeO2 interfaces, and exploring how it can affect ionic conduction. Candidate structures of the DFT validation calculations.","base_url":"https://aiida.materialscloud.org/stoceriaitf/optimade","homepage":"https://materialscloud.org/explore/stoceriaitf","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"tc-applicability":{"id":"tc-applicability","type":"links","attributes":{"name":"Applicability of tail-corrections in the molecular simulations of porous materials","description":"Tail-corrections in molecular simulations for adsorption of gasses in a diverse set of nanoporous crystalline materials (zeolites, Covalent Organic Framworks (COFs), and Metal Organic Frameworks (MOFs)).","base_url":"https://aiida.materialscloud.org/tc-applicability/optimade","homepage":"https://materialscloud.org/explore/tc-applicability","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"tcod":{"id":"tcod","type":"links","attributes":{"name":"Theoretical Crystallography Open Database","description":"Open-access collection of theoretically calculated or refined crystal structures of organic, inorganic, metal-organic compounds and minerals, excluding biopolymers","base_url":"https://www.crystallography.net/tcod/optimade","homepage":"https://www.crystallography.net/tcod","link_type":"child","api_version":"1.1.0","query_limits":[100]}},"tin-antimony-sulfoiodide":{"id":"tin-antimony-sulfoiodide","type":"links","attributes":{"name":"Hidden spontaneous polarisation in the chalcohalide photovoltaic Sn2SbS2I3","description":"Structural, dynamic and electronic characterisation of a novel mixed-metal chalcohalide revealing hidden symmetry breaking and spontaneous polarisation.","base_url":"https://aiida.materialscloud.org/tin-antimony-sulfoiodide/optimade","homepage":"https://materialscloud.org/explore/tin-antimony-sulfoiodide","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"twodmatpedia":{"id":"twodmatpedia","type":"links","attributes":{"name":"2DMatpedia","description":"2DMatpedia, an open computational database of two-dimensional materials from top-down and bottom-up approaches","base_url":"http://optimade.2dmatpedia.org","homepage":"http://2dmatpedia.org","link_type":"child","api_version":"1.1.0","query_limits":[500]}}},"apis":{"2dstructures":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/2dstructures/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"2dtopo":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/2dtopo/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"aflow":[{"type":"info","id":"/","attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"https://aflow.org/API/optimade/v0.9/","version":"0.9.0"},{"url":"https://aflow.org/API/optimade/v1.0/","version":"1.0.0"},{"url":"https://aflow.org/API/optimade/v1.1/","version":"1.1.0"}],"formats":["json"],"entry_types_by_format":{"json":["structures","calculations"]},"available_endpoints":["structures","calculations","info","links"]},"is_index":false}],"cod":[{"attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://www.crystallography.net/cod/optimade/v1.1.0/","version":"1.1.0"}],"available_endpoints":["references","structures"],"entry_types_by_format":{"json":["references","structures"]},"formats":["json"]},"id":"/","type":"info"}],"curated-cofs":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/curated-cofs/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"jarvis":[{"type":"info","id":"/","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://jarvis.nist.gov/optimade/jarvisdft/v1","version":"1.1.0"}],"formats":["json","xml","yaml"],"entry_types_by_format":{"json":["structures"],"xml":["structures"],"yaml":["structures"]},"available_endpoints":["structures","info","links","versions"],"is_index":false}}],"li-ion-conductors":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/li-ion-conductors/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"mc3d-structures":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/mc3d-structures/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"mp":[{"id":"/","type":"info","attributes":{"api_version":"1.0.1","available_api_versions":[{"url":"http://optimade.materialsproject.org/v1","version":"1.0.1"}],"formats":["json"],"available_endpoints":["info","links","structures","references"],"entry_types_by_format":{"json":["structures","references"]},"is_index":false}}],"mpds":[{"type":"info","attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"https://api.mpds.io/v1","version":"1.0.0"}],"available_endpoints":["structures","extensions/properties","extensions/phase_diagrams","extensions/phases"],"formats":["json"],"entry_types_by_format":{"json":["structures","extensions/properties","extensions/phase_diagrams","extensions/phases"]}}}],"nmd":[{"id":"/","type":"info","attributes":{"api_version":"1.0.1","available_api_versions":[{"url":"http://nomad-lab.eu/v1","version":"1.0.1"}],"formats":["json"],"available_endpoints":["info","links","structures","references"],"entry_types_by_format":{"json":["structures","references"]},"is_index":false}}],"odbx":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://optimade.odbx.science/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","structures","references"],"entry_types_by_format":{"json":["structures","references"]},"is_index":false}}],"omdb_production":[{"attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"http://optimade.openmaterialsdb.se/v1","version":"1.0.0"},{"url":"http://optimade.openmaterialsdb.se/v1.0","version":"1.0.0"},{"url":"http://optimade.openmaterialsdb.se/v1.0.0","version":"1.0.0"}],"available_endpoints":["info","links","structures"],"entry_types_by_format":{"json":["structures"]},"formats":["json"],"is_index":false},"id":"/","type":"info"}],"optimade-sample":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/optimade-sample/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"pyrene-mofs":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/pyrene-mofs/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"scdm":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/autowannier/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"sssp":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/sssplibrary/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"stoceriaitf":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/stoceriaitf/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"tc-applicability":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/tc-applicability/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"tcod":[{"attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://www.crystallography.net/tcod/optimade/v1.1.0/","version":"1.1.0"}],"available_endpoints":["references","structures"],"entry_types_by_format":{"json":["references","structures"]},"formats":["json"]},"id":"/","type":"info"}],"tin-antimony-sulfoiodide":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/tin-antimony-sulfoiodide/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"twodmatpedia":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"http://optimade.2dmatpedia.org/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","structures","references"],"entry_types_by_format":{"json":["structures","references"]},"is_index":false}}]}}
@@ -1 +1 @@
1
- {"2dstructures":{"id":"2dstructures","type":"links","attributes":{"name":"2D Structures","description":"Two-dimensional (2D) materials from high-throughput computational exfoliation of experimentally known compounds.","base_url":"https://aiida.materialscloud.org/2dstructures/optimade","homepage":"https://materialscloud.org/explore/2dstructures","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"2dtopo":{"id":"2dtopo","type":"links","attributes":{"name":"2D topological insulators","description":"Quantum spin Hall insulator (QSHI) candidates through DFT band structure calculations of a database with 1825 compounds.","base_url":"https://aiida.materialscloud.org/2dtopo/optimade","homepage":"https://materialscloud.org/explore/2dtopo","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"aflow":{"id":"aflow","type":"links","attributes":{"name":"AFLOW","description":"The AFLOW OPTIMADE endpoint","base_url":"http://aflow.org/API/optimade/","homepage":"http://aflow.org","link_type":"child"}},"cod":{"id":"cod","type":"links","attributes":{"name":"Crystallography Open Database","description":"Open-access collection of crystal structures of organic, inorganic, metal-organics compounds and minerals, excluding biopolymers","base_url":"https://www.crystallography.net/cod/optimade","homepage":"https://www.crystallography.net/cod","link_type":"child"}},"curated-cofs":{"id":"curated-cofs","type":"links","attributes":{"name":"CURATED covalent organic frameworks database","description":"Database of experimentally reported Covalent-Organic Frameworks (COFs), provided with DFT-optimized geometry and DDEC partial charges for molecular simulations.","base_url":"https://aiida.materialscloud.org/curated-cofs/optimade","homepage":"https://materialscloud.org/discover/curated-cofs","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"jarvis":{"id":"jarvis","type":"links","attributes":{"name":"JARVIS-DFT","description":"JARVIS-DFT is a materials property repository focused on density functional theory (DFT) predictions of material properties, especially for crystalline materials.","base_url":"https://jarvis.nist.gov/optimade/jarvisdft","homepage":"https://jarvis.nist.gov","link_type":"child"}},"li-ion-conductors":{"id":"li-ion-conductors","type":"links","attributes":{"name":"Solid-state Li-ion conductors.","description":"High-throughput computational screening study for solid-state Li-ion conductors.","base_url":"https://aiida.materialscloud.org/li-ion-conductors/optimade","homepage":"https://materialscloud.org/explore/li-ion-conductors","link_type":"child","aggregate":"staging","no_aggregate_reason":null}},"mp":{"id":"mp","type":"links","attributes":{"name":"The Materials Project","description":"The Materials Project OPTIMADE endpoint","base_url":"https://optimade.materialsproject.org","homepage":"https://www.materialsproject.org","link_type":"child"}},"mpds":{"id":"mpds","type":"links","attributes":{"name":"Materials Platform for Data Science","description":"A highly curated Pauling File dataset based on ~0.5M publications and backing up Springer Materials, ICDD PDF, ASM APD, MedeA, Pearson Crystal Data, AtomWork Advanced, etc.","base_url":"https://api.mpds.io","homepage":"https://mpds.io","link_type":"child"}},"nmd":{"id":"nmd","type":"links","attributes":{"name":"novel materials discovery (NOMAD)","description":"A FAIR data sharing platform for materials science data","base_url":"https://nomad-lab.eu/prod/rae/optimade/","homepage":"https://nomad-lab.eu","link_type":"child"}},"odbx":{"id":"odbx","type":"links","attributes":{"name":"odbx","description":"The Open Database of Xtals is run by the group of Dr Andrew Morris at the universities of Birmingham and Cambridge and is constructed using the matador library.","base_url":"https://optimade.odbx.science","homepage":"https://odbx.science","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"omdb_production":{"id":"omdb_production","type":"links","attributes":{"name":"Open Materials Database (omdb) production database","description":"This is the main production version of the Open Materials Database","base_url":"http://optimade.openmaterialsdb.se","homepage":"http://openmaterialsdb.se","link_type":"child"}},"optimade-sample":{"id":"optimade-sample","type":"links","attributes":{"name":"OPTIMADE Sample Database","description":"Database with example structures for OPTIMADE tests.","base_url":"https://aiida.materialscloud.org/optimade-sample/optimade","homepage":"https://materialscloud.org/explore/optimade-sample","link_type":"child","aggregate":"test","no_aggregate_reason":null}},"oqmd":{"id":"oqmd","type":"links","attributes":{"name":"The OQMD","description":"The Open Quantum Materials Database endpoint","base_url":"http://oqmd.org/optimade/","homepage":"http://oqmd.org","link_type":"child"}},"pyrene-mofs":{"id":"pyrene-mofs","type":"links","attributes":{"name":"Pyrene MOFs","description":"Pyrene Metal Organic Frameworks (MOFs).","base_url":"https://aiida.materialscloud.org/pyrene-mofs/optimade","homepage":"https://materialscloud.org/discover/pyrene-mofs","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"scdm":{"id":"scdm","type":"links","attributes":{"name":"Automated high-throughput Wannierisation","description":"Validation results of an automated protocol for generating maximally-localized Wannier functions in a high-throughput framework.","base_url":"https://aiida.materialscloud.org/autowannier/optimade","homepage":"https://materialscloud.org/explore/autowannier","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"sssp":{"id":"sssp","type":"links","attributes":{"name":"Standard solid-state pseudopotentials (SSSP)","description":"It contains data generated from the testing protocol of the standard solid-state pseudopotentials library.\n","base_url":"https://aiida.materialscloud.org/sssplibrary/optimade","homepage":"https://materialscloud.org/explore/sssplibrary","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"stoceriaitf":{"id":"stoceriaitf","type":"links","attributes":{"name":"SrTiO3-CeO2 interfaces","description":"Refining random structure searching results of SrTiO3-CeO2 interfaces, and exploring how it can affect ionic conduction. Candidate structures of the DFT validation calculations.","base_url":"https://aiida.materialscloud.org/stoceriaitf/optimade","homepage":"https://materialscloud.org/explore/stoceriaitf","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"tc-applicability":{"id":"tc-applicability","type":"links","attributes":{"name":"Applicability of tail-corrections in the molecular simulations of porous materials","description":"Tail-corrections in molecular simulations for adsorption of gasses in a diverse set of nanoporous crystalline materials (zeolites, Covalent Organic Framworks (COFs), and Metal Organic Frameworks (MOFs)).","base_url":"https://aiida.materialscloud.org/tc-applicability/optimade","homepage":"https://materialscloud.org/explore/tc-applicability","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"tcod":{"id":"tcod","type":"links","attributes":{"name":"Theoretical Crystallography Open Database","description":"Open-access collection of theoretically calculated or refined crystal structures of organic, inorganic, metal-organic compounds and minerals, excluding biopolymers","base_url":"https://www.crystallography.net/tcod/optimade","homepage":"https://www.crystallography.net/tcod","link_type":"child"}},"threedd":{"id":"threedd","type":"links","attributes":{"name":"Three-dimensional crystals database","description":"Curated set of relaxed three-dimensional crystal structures based on raw CIF data from the experimantal databases MPDS, COD, and ICSD.","base_url":"https://aiida.materialscloud.org/3dd/optimade","homepage":"https://materialscloud.org/explore/3dd","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"tin-antimony-sulfoiodide":{"id":"tin-antimony-sulfoiodide","type":"links","attributes":{"name":"Hidden spontaneous polarisation in the chalcohalide photovoltaic Sn2SbS2I3","description":"Structural, dynamic and electronic characterisation of a novel mixed-metal chalcohalide revealing hidden symmetry breaking and spontaneous polarisation.","base_url":"https://aiida.materialscloud.org/tin-antimony-sulfoiodide/optimade","homepage":"https://materialscloud.org/explore/tin-antimony-sulfoiodide","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"twodmatpedia":{"id":"twodmatpedia","type":"links","attributes":{"name":"2DMatpedia","description":"2DMatpedia, an open computational database of two-dimensional materials from top-down and bottom-up approaches","base_url":"http://optimade.2dmatpedia.org","homepage":"http://2dmatpedia.org","link_type":"child"}}}
1
+ {"2dstructures":{"id":"2dstructures","type":"links","attributes":{"name":"2D Structures","description":"Two-dimensional (2D) materials from high-throughput computational exfoliation of experimentally known compounds.","base_url":"https://aiida.materialscloud.org/2dstructures/optimade","homepage":"https://materialscloud.org/explore/2dstructures","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"2dtopo":{"id":"2dtopo","type":"links","attributes":{"name":"2D topological insulators","description":"Quantum spin Hall insulator (QSHI) candidates through DFT band structure calculations.","base_url":"https://aiida.materialscloud.org/2dtopo/optimade","homepage":"https://materialscloud.org/explore/2dtopo","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"aflow":{"id":"aflow","type":"links","attributes":{"name":"AFLOW","description":"The AFLOW OPTIMADE endpoint","base_url":"http://aflow.org/API/optimade/","homepage":"http://aflow.org","link_type":"child"}},"cod":{"id":"cod","type":"links","attributes":{"name":"Crystallography Open Database","description":"Open-access collection of crystal structures of organic, inorganic, metal-organics compounds and minerals, excluding biopolymers","base_url":"https://www.crystallography.net/cod/optimade","homepage":"https://www.crystallography.net/cod","link_type":"child"}},"curated-cofs":{"id":"curated-cofs","type":"links","attributes":{"name":"CURATED covalent organic frameworks database","description":"Database of experimentally reported Covalent-Organic Frameworks (COFs), provided with DFT-optimized geometry and DDEC partial charges for molecular simulations.","base_url":"https://aiida.materialscloud.org/curated-cofs/optimade","homepage":"https://materialscloud.org/discover/curated-cofs","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"jarvis":{"id":"jarvis","type":"links","attributes":{"name":"JARVIS-DFT","description":"JARVIS-DFT is a materials property repository focused on density functional theory (DFT) predictions of material properties, especially for crystalline materials.","base_url":"https://jarvis.nist.gov/optimade/jarvisdft","homepage":"https://jarvis.nist.gov","link_type":"child"}},"li-ion-conductors":{"id":"li-ion-conductors","type":"links","attributes":{"name":"Solid-state Li-ion conductors.","description":"High-throughput computational screening study for solid-state Li-ion conductors.","base_url":"https://aiida.materialscloud.org/li-ion-conductors/optimade","homepage":"https://materialscloud.org/explore/li-ion-conductors","link_type":"child","aggregate":"staging","no_aggregate_reason":null}},"mc3d-structures":{"id":"mc3d-structures","type":"links","attributes":{"name":"Materials Cloud three-dimensional crystals database (MC3D)","description":"Curated set of relaxed three-dimensional crystal structures based on raw CIF data from the experimantal databases MPDS, COD, and ICSD.","base_url":"https://aiida.materialscloud.org/mc3d-structures/optimade","homepage":"https://materialscloud.org/explore/mc3d-structures","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"mp":{"id":"mp","type":"links","attributes":{"name":"The Materials Project","description":"The Materials Project OPTIMADE endpoint","base_url":"https://optimade.materialsproject.org","homepage":"https://www.materialsproject.org","link_type":"child"}},"mpds":{"id":"mpds","type":"links","attributes":{"name":"Materials Platform for Data Science","description":"A highly curated Pauling File dataset based on ~0.5M publications and backing up Springer Materials, ICDD PDF, ASM APD, MedeA, Pearson Crystal Data, AtomWork Advanced, etc.","base_url":"https://api.mpds.io","homepage":"https://mpds.io","link_type":"child"}},"nmd":{"id":"nmd","type":"links","attributes":{"name":"novel materials discovery (NOMAD)","description":"A FAIR data sharing platform for materials science data","base_url":"https://nomad-lab.eu/prod/rae/optimade/","homepage":"https://nomad-lab.eu","link_type":"child"}},"odbx":{"id":"odbx","type":"links","attributes":{"name":"odbx","description":"The Open Database of Xtals is run by the group of Dr Andrew Morris at the universities of Birmingham and Cambridge and is constructed using the matador library.","base_url":"https://optimade.odbx.science","homepage":"https://odbx.science","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"omdb_production":{"id":"omdb_production","type":"links","attributes":{"name":"Open Materials Database (omdb) production database","description":"This is the main production version of the Open Materials Database","base_url":"http://optimade.openmaterialsdb.se","homepage":"http://openmaterialsdb.se","link_type":"child"}},"optimade-sample":{"id":"optimade-sample","type":"links","attributes":{"name":"OPTIMADE Sample Database","description":"Database with example structures for OPTIMADE tests.","base_url":"https://aiida.materialscloud.org/optimade-sample/optimade","homepage":"https://materialscloud.org/explore/optimade-sample","link_type":"child","aggregate":"test","no_aggregate_reason":null}},"pyrene-mofs":{"id":"pyrene-mofs","type":"links","attributes":{"name":"Pyrene MOFs","description":"Pyrene Metal Organic Frameworks (MOFs).","base_url":"https://aiida.materialscloud.org/pyrene-mofs/optimade","homepage":"https://materialscloud.org/discover/pyrene-mofs","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"scdm":{"id":"scdm","type":"links","attributes":{"name":"Automated high-throughput Wannierisation","description":"Validation results of an automated protocol for generating maximally-localized Wannier functions in a high-throughput framework.","base_url":"https://aiida.materialscloud.org/autowannier/optimade","homepage":"https://materialscloud.org/explore/autowannier","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"sssp":{"id":"sssp","type":"links","attributes":{"name":"Standard solid-state pseudopotentials (SSSP)","description":"It contains data generated from the testing protocol of the standard solid-state pseudopotentials library.\n","base_url":"https://aiida.materialscloud.org/sssplibrary/optimade","homepage":"https://materialscloud.org/explore/sssplibrary","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"stoceriaitf":{"id":"stoceriaitf","type":"links","attributes":{"name":"SrTiO3-CeO2 interfaces","description":"Refining random structure searching results of SrTiO3-CeO2 interfaces, and exploring how it can affect ionic conduction. Candidate structures of the DFT validation calculations.","base_url":"https://aiida.materialscloud.org/stoceriaitf/optimade","homepage":"https://materialscloud.org/explore/stoceriaitf","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"tc-applicability":{"id":"tc-applicability","type":"links","attributes":{"name":"Applicability of tail-corrections in the molecular simulations of porous materials","description":"Tail-corrections in molecular simulations for adsorption of gasses in a diverse set of nanoporous crystalline materials (zeolites, Covalent Organic Framworks (COFs), and Metal Organic Frameworks (MOFs)).","base_url":"https://aiida.materialscloud.org/tc-applicability/optimade","homepage":"https://materialscloud.org/explore/tc-applicability","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"tcod":{"id":"tcod","type":"links","attributes":{"name":"Theoretical Crystallography Open Database","description":"Open-access collection of theoretically calculated or refined crystal structures of organic, inorganic, metal-organic compounds and minerals, excluding biopolymers","base_url":"https://www.crystallography.net/tcod/optimade","homepage":"https://www.crystallography.net/tcod","link_type":"child"}},"tin-antimony-sulfoiodide":{"id":"tin-antimony-sulfoiodide","type":"links","attributes":{"name":"Hidden spontaneous polarisation in the chalcohalide photovoltaic Sn2SbS2I3","description":"Structural, dynamic and electronic characterisation of a novel mixed-metal chalcohalide revealing hidden symmetry breaking and spontaneous polarisation.","base_url":"https://aiida.materialscloud.org/tin-antimony-sulfoiodide/optimade","homepage":"https://materialscloud.org/explore/tin-antimony-sulfoiodide","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"twodmatpedia":{"id":"twodmatpedia","type":"links","attributes":{"name":"2DMatpedia","description":"2DMatpedia, an open computational database of two-dimensional materials from top-down and bottom-up approaches","base_url":"http://optimade.2dmatpedia.org","homepage":"http://2dmatpedia.org","link_type":"child"}}}
@@ -10,14 +10,28 @@ export declare class Optimade {
10
10
  providersUrl?: string;
11
11
  corsProxyUrl?: string;
12
12
  });
13
+ addProvider(provider: Types.Provider): Promise<Types.ProvidersMap>;
13
14
  getProviders(api?: Types.Api): Promise<Types.ProvidersMap | null>;
14
15
  getApis(provider: Types.Provider | string, version?: string): Promise<Types.Api | null>;
15
- getStructures(providerId: string, filter: string, page: number, limit: number): Promise<Types.StructuresResponse[] | Types.ResponseError>;
16
- getStructuresAll(providerIds: string[], filter: string, page: number, limit: number, batch?: boolean): Promise<Promise<Types.StructuresResult>[]> | Promise<Types.StructuresResult>[];
16
+ getStructures({ providerId, filter, page, limit, offset }: {
17
+ providerId: string;
18
+ filter: string;
19
+ page: number;
20
+ limit: number;
21
+ offset: number;
22
+ }): Promise<Types.StructuresResponse[] | Types.ResponseError>;
23
+ getStructuresAll({ providers, filter, page, limit, offset, batch }: {
24
+ providers: string[];
25
+ filter: string;
26
+ page: number;
27
+ limit: number;
28
+ offset: number;
29
+ batch?: boolean;
30
+ }): Promise<Promise<Types.StructuresResult>[]> | Promise<Types.StructuresResult>[];
17
31
  private followLinks;
18
32
  private wrapUrl;
19
33
  private isDuplicatedReq;
20
- static getJSON(uri: string, params?: {}, headers?: {}): Promise<any>;
34
+ static getJSON(uri: string, params?: any, headers?: {}): Promise<any>;
21
35
  static isProviderValid(provider: Types.Provider): boolean;
22
36
  static apiVersionUrl({ attributes: { api_version, available_api_versions } }: Types.Api): any;
23
37
  static apiVersion({ data, meta }: Types.InfoResponse): Types.Api;
@@ -43,7 +43,7 @@ export interface Api {
43
43
  api_version: string;
44
44
  available_api_versions: ApiVer | ApiVer[];
45
45
  available_endpoints: string[];
46
- entry_types_by_format: {};
46
+ entry_types_by_format: Record<string, unknown>;
47
47
  formats: string[];
48
48
  };
49
49
  }
@@ -57,6 +57,7 @@ export interface Provider {
57
57
  homepage?: string | null;
58
58
  link_type?: string;
59
59
  query_limits?: number[];
60
+ api_version?: string;
60
61
  };
61
62
  }
62
63
  export interface Structure {
File without changes
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "optimade",
3
- "version": "2.0.3",
3
+ "version": "2.1.0",
4
4
  "description": "Aggregating Optimade client for the online materials databases",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",
8
8
  "scripts": {
9
9
  "build": "npm run lint && rollup --config",
10
- "lint": "tslint -c tslint.json \"src/**/*.ts\"",
11
- "lint:fix": "tslint --fix -c tslint.json \"src/**/*.ts\"",
10
+ "lint": "eslint './src/**/*.ts'",
11
+ "lint:fix": "eslint --fix './src/**/*.ts'",
12
12
  "prepublishOnly": "npm run build && npm run prefetch",
13
13
  "test": "echo \"Error: no test specified\" && exit 1",
14
14
  "prefetch": "node prefetch.js"
@@ -16,17 +16,28 @@
16
16
  "author": "Pavel Malyshev",
17
17
  "license": "MIT",
18
18
  "devDependencies": {
19
+ "@types/eslint": "^8.4.2",
20
+ "@typescript-eslint/eslint-plugin": "^5.25.0",
21
+ "@typescript-eslint/parser": "^5.25.0",
22
+ "@rollup/plugin-json": "^4.1.0",
19
23
  "@types/jest": "^26.0.15",
20
24
  "jest": "^26.6.0",
21
25
  "rollup": "^2.47.0",
22
26
  "rollup-plugin-typescript2": "^0.28.0",
23
27
  "ts-jest": "^26.4.1",
24
- "tslint": "^6.1.3",
25
- "tslint-eslint-rules": "^5.4.0",
28
+ "eslint": "^8.16.0",
26
29
  "typescript": "^4.0.3"
27
30
  },
28
31
  "dependencies": {
29
32
  "isomorphic-unfetch": "^3.1.0",
30
33
  "node-abort-controller": "^3.0.1"
34
+ },
35
+ "keywords": [
36
+ "optimade",
37
+ "materials"
38
+ ],
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "git+https://github.com/tilde-lab/optimade-client"
31
42
  }
32
43
  }
package/prefetch.js CHANGED
@@ -14,27 +14,39 @@ const optimade = new Optimade({
14
14
  providersUrl: 'https://providers.optimade.org/providers.json'
15
15
  });
16
16
 
17
- optimade.getProviders().then(async () => {
17
+ let time = performance.now(),
18
+ alltime = performance.now(),
19
+ skip = process.env.SKIP;
20
+ // || 'oqmd, jarvis';
21
+
22
+ optimade.getProviders().then(async (providers) => {
23
+
24
+ console.warn('providers fetched from source', performance.now() - time);
25
+ time = performance.now();
18
26
 
19
27
  const filteredApis = Object.entries(optimade.apis).filter(([k, v]) => v.length);
20
28
  const apis = filteredApis.sort().reduce((acc, [k, v]) => {
21
29
  return { ...acc, ...{ [k]: v } };
22
30
  }, {});
23
31
 
24
- const source = Object.keys(optimade.providers).sort().reduce(
32
+ const source = Object.keys(providers).sort().reduce(
25
33
  (obj, key) => {
26
- obj[key] = optimade.providers[key];
34
+ obj[key] = providers[key];
27
35
  return obj;
28
36
  }, {});
29
37
 
30
- async function getQueryLimits(providers, max = 1000) {
38
+ console.warn('providers sorted', performance.now() - time);
39
+
40
+ async function getQueryLimits(providers, skip = '', max = 1000) {
41
+
42
+ providers = Object.fromEntries(Object.entries(providers).filter(([key]) => !skip.includes(key)));
31
43
 
32
44
  const fetchLimits = async (k, v) => {
33
45
  const formula = `chemical_formula_anonymous="A2B"`;
34
46
  const url = `${v.attributes.base_url}/v1/structures?filter=${formula}&page_limit=${max}`;
35
47
  try {
36
48
  const res = await fetch(url).then(res => res.json());
37
- const api = res.meta && res.meta.api_version;
49
+ const api = res.meta && res.meta.api_version || apis[k][0].attributes.api_version;
38
50
  //console.dir(res);
39
51
  const detail = (e) => {
40
52
  return e
@@ -44,29 +56,33 @@ optimade.getProviders().then(async () => {
44
56
  : '0';
45
57
  };
46
58
  const nums = detail(res.errors).match(/\d+/g).filter(n => +n < max).map(n => +n);
47
- if (!nums.includes(0))
48
- return {
49
- [k]: { ...v, attributes: { ...v.attributes, api_version: api, ['query_limits']: nums } }
50
- };
59
+ return {
60
+ [k]: { ...v, attributes: { ...v.attributes, api_version: api, ['query_limits']: !nums.includes(0) ? nums : [10] } }
61
+ };
51
62
  } catch (error) {
52
63
  console.log(error);
53
64
  }
54
65
  };
55
-
56
- providers = await Object.entries(providers).reduce(async (promise, [k, v]) => {
66
+ time = performance.now();
67
+ return await Object.entries(providers).reduce(async (promise, [k, v], i) => {
57
68
  const provider = await fetchLimits(k, v);
58
69
  const acc = await promise;
70
+ console.log(i, provider);
59
71
  return { ...acc, ...provider };
60
72
  }, Promise.resolve({}));
61
-
62
- //const log = { prefetched: Object.keys(providers).length, source: Object.keys(source).length };
63
- //console.log(log);
64
-
65
- return providers;
66
73
  }
67
74
 
68
- getQueryLimits(source).then(providers => {
75
+ getQueryLimits(source, skip).then(providers => {
69
76
  const data = { providers, apis };
77
+
78
+ console.warn('limits fetched', performance.now() - time);
79
+
80
+ console.log({
81
+ prefetched: Object.keys(providers).length,
82
+ source: Object.keys(source).length,
83
+ alltime: performance.now() - alltime
84
+ });
85
+
70
86
  fs.writeFile(path.join(__dirname, 'dist/prefetched.json'), JSON.stringify(data), (err) => {
71
87
  if (err) throw err;
72
88
  console.log('The prefetched.json file has been saved!');
package/rollup.config.js CHANGED
@@ -1,4 +1,7 @@
1
+ /* jshint esversion: 6 */
2
+
1
3
  import typescript from 'rollup-plugin-typescript2';
4
+ import json from '@rollup/plugin-json';
2
5
 
3
6
  import pkg from './package.json';
4
7
 
@@ -14,5 +17,6 @@ export default {
14
17
  ],
15
18
  plugins: [
16
19
  typescript(),
20
+ json(),
17
21
  ],
18
22
  };
package/src/index.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import { allSettled, fetchWithTimeout } from './utils';
2
+ import { version } from '../package.json'
2
3
 
3
4
  import type * as Types from './types';
4
5
  export { Types };
5
6
 
6
7
  export class Optimade {
7
- private providersUrl: string = '';
8
- private corsProxyUrl: string = '';
8
+ private providersUrl = '';
9
+ private corsProxyUrl = '';
9
10
  providers: Types.ProvidersMap | null = null;
10
11
  apis: Types.ApisMap = {};
11
12
  private reqStack: string[] = [];
@@ -15,24 +16,74 @@ export class Optimade {
15
16
  this.providersUrl = this.wrapUrl(providersUrl);
16
17
  }
17
18
 
19
+ async addProvider(provider: Types.Provider) {
20
+ if (!this.apis[provider.id]) { this.apis[provider.id] = []; }
21
+
22
+ try {
23
+ const ver = provider.attributes
24
+ && provider.attributes.api_version ?
25
+ provider.attributes.api_version.charAt(0) : '';
26
+ const api = await this.getApis(provider, ver ? `v${ver}` : '');
27
+
28
+ if (api.attributes.available_endpoints.includes('structures')) {
29
+ this.apis[provider.id].push(api);
30
+ }
31
+
32
+ } catch (ignore) { console.log(ignore) }
33
+
34
+ if (!provider.attributes.query_limits) {
35
+ const formula = `chemical_formula_anonymous="A2B"`;
36
+ const url = `${provider.attributes.base_url}/v1/structures?filter=${formula}&page_limit=1000`;
37
+
38
+ try {
39
+ const res = await fetch(url).then(res => res.json());
40
+ const version = res.meta && res.meta.api_version || this.apis[provider.id][0].attributes.api_version;
41
+ const detail = (errors) => {
42
+ return errors
43
+ ? errors.length
44
+ ? errors[0].detail
45
+ : errors.detail
46
+ : '10';
47
+ };
48
+ const limits = detail(res.errors)
49
+ .match(/\d+/g)
50
+ .filter((number: string) => +number < 1000)
51
+ .map((number: string) => +number);
52
+
53
+ provider.attributes = {
54
+ ...provider.attributes,
55
+ api_version: version,
56
+ query_limits: limits
57
+ }
58
+
59
+ } catch (error) {
60
+ console.log(error);
61
+ }
62
+ }
63
+
64
+ this.providers[provider.id] = provider
65
+
66
+ return this.providers;
67
+ }
68
+
18
69
  async getProviders(api?: Types.Api): Promise<Types.ProvidersMap | null> {
19
70
  const providers: Types.ProvidersResponse | null = await (api ?
20
71
  this.followLinks(api).catch(() => null) :
21
72
  Optimade.getJSON(this.providersUrl).catch(() => null)
22
73
  );
23
74
 
24
- if (!providers) return null;
25
- if (!this.providers) this.providers = {};
75
+ if (!providers) { return null; }
76
+ if (!this.providers) { this.providers = {}; }
26
77
 
27
78
  const data = providers.data.filter(Optimade.isProviderValid);
28
79
  const ver = providers.meta && providers.meta.api_version ?
29
80
  providers.meta.api_version.charAt(0) : '';
30
81
 
31
82
  for (const provider of data) {
32
- if (!this.apis[provider.id]) this.apis[provider.id] = [];
83
+ if (!this.apis[provider.id]) { this.apis[provider.id] = []; }
33
84
  try {
34
85
  const api = await this.getApis(provider, ver ? `v${ver}` : '');
35
- if (!api) continue;
86
+ if (!api) { continue; }
36
87
 
37
88
  if (api.attributes.available_endpoints.includes('structures')) {
38
89
  this.apis[provider.id].push(api);
@@ -42,41 +93,40 @@ export class Optimade {
42
93
  } else {
43
94
  await this.getProviders(api);
44
95
  }
45
- } catch (ignore) { }
96
+ } catch (ignore) { console.log(ignore) }
46
97
  }
47
98
 
48
99
  return this.providers;
49
100
  }
50
101
 
51
- async getApis(provider: Types.Provider | string, version: string = ''): Promise<Types.Api | null> {
102
+ async getApis(provider: Types.Provider | string, version = ''): Promise<Types.Api | null> {
52
103
  if (typeof provider === 'string') {
53
104
  provider = this.providers[provider];
54
105
  }
55
106
 
56
- if (!provider) throw new Error('No provider found');
107
+ if (!provider) { throw new Error('No provider found'); }
57
108
 
58
109
  const url: string = this.wrapUrl(`${provider.attributes.base_url}/${version}`, '/info');
59
110
 
60
- if (this.isDuplicatedReq(url)) return null;
111
+ if (this.isDuplicatedReq(url)) { return null; }
61
112
 
62
113
  const apis: Types.InfoResponse = await Optimade.getJSON(url);
63
114
  return Optimade.apiVersion(apis);
64
115
  }
65
116
 
66
- async getStructures(providerId: string, filter: string = '', page: number = 1, limit: number): Promise<Types.StructuresResponse[] | Types.ResponseError> {
117
+ async getStructures({ providerId, filter, page, limit, offset }: { providerId: string; filter: string; page: number; limit: number; offset: number; }): Promise<Types.StructuresResponse[] | Types.ResponseError> {
67
118
 
68
- if (!this.apis[providerId]) return null;
119
+ if (!this.apis[providerId]) { return null; }
69
120
 
70
121
  const apis = this.apis[providerId].filter(api => api.attributes.available_endpoints.includes('structures'));
71
122
  const provider = this.providers[providerId];
72
123
 
73
124
  const structures: Types.StructuresResponse[] = await allSettled(apis.map(async (api: Types.Api) => {
74
- if (page <= 0) page = 1;
75
125
  const pageLimit = limit ? `&page_limit=${limit}` : '';
76
- const pageNumber = page ? `&page_number=${page - 1}` : '';
77
- const pageOffset = limit && page ? `&page_offset=${limit * (page - 1)}` : '';
126
+ const pageNumber = page ? `&page_number=${page}` : '';
127
+ const pageOffset = offset ? `&page_offset=${offset}` : '';
78
128
  const params = filter ? `${pageLimit + pageNumber + pageOffset}` : `?${pageLimit}`;
79
- const url: string = this.wrapUrl(Optimade.apiVersionUrl(api), filter ? `/structures?filter=${filter + params}` : `/structures${params}`);
129
+ const url = this.wrapUrl(Optimade.apiVersionUrl(api), filter ? `/structures?filter=${filter + params}` : `/structures${params}`);
80
130
 
81
131
  try {
82
132
  return await Optimade.getJSON(url, {}, { Origin: 'https://cors.optimade.science', 'X-Requested-With': 'XMLHttpRequest' });
@@ -98,13 +148,13 @@ export class Optimade {
98
148
  }, []);
99
149
  }
100
150
 
101
- getStructuresAll(providerIds: string[], filter: string = '', page: number = 0, limit: number, batch: boolean = true): Promise<Promise<Types.StructuresResult>[]> | Promise<Types.StructuresResult>[] {
151
+ getStructuresAll({ providers, filter, page, limit, offset, batch = true }: { providers: string[]; filter: string; page: number; limit: number; offset: number; batch?: boolean; }): Promise<Promise<Types.StructuresResult>[]> | Promise<Types.StructuresResult>[] {
102
152
 
103
- const results = providerIds.reduce((structures: Promise<any>[], providerId: string) => {
153
+ const results = providers.reduce((structures: Promise<any>[], providerId: string) => {
104
154
  const provider = this.providers[providerId];
105
155
  if (provider) {
106
156
  structures.push(allSettled([
107
- this.getStructures(providerId, filter, page, limit),
157
+ this.getStructures({ providerId, filter, page, limit, offset }),
108
158
  Promise.resolve(provider)
109
159
  ]));
110
160
  }
@@ -115,14 +165,14 @@ export class Optimade {
115
165
  }
116
166
 
117
167
  private async followLinks(api: Types.Api): Promise<Types.LinksResponse | null> {
118
- if (!api.attributes.available_endpoints.includes('links')) return null;
168
+ if (!api.attributes.available_endpoints.includes('links')) { return null; }
119
169
 
120
170
  const url = this.wrapUrl(Optimade.apiVersionUrl(api), '/links');
121
171
 
122
172
  return !this.isDuplicatedReq(url) ? Optimade.getJSON(url) : null;
123
173
  }
124
174
 
125
- private wrapUrl(url, tail = '') {
175
+ private wrapUrl(url: string, tail = ''): string {
126
176
  url = this.corsProxyUrl ? `${this.corsProxyUrl}/${url.replace('://', '/').replace('//', '/')}` : url;
127
177
  return tail ? url.replace(/\/$/, '') + tail : url;
128
178
  }
@@ -131,7 +181,7 @@ export class Optimade {
131
181
  return this.reqStack.includes(url) || !this.reqStack.unshift(url);
132
182
  }
133
183
 
134
- static async getJSON(uri: string, params: {} = null, headers: {} = {}) {
184
+ static async getJSON(uri: string, params = null, headers = {}) {
135
185
 
136
186
  const url = new URL(uri);
137
187
  const timeout = 10000;
@@ -140,6 +190,8 @@ export class Optimade {
140
190
  Object.entries(params).forEach((param: [string, any]) => url.searchParams.append(...param));
141
191
  }
142
192
 
193
+ Object.assign(headers, { 'User-Agent': `tilde-lab-optimade-client/${version}` })
194
+
143
195
  const res = await fetchWithTimeout(url.toString(), { headers }, timeout);
144
196
 
145
197
  if (!res.ok) {
package/src/types.ts CHANGED
@@ -46,7 +46,7 @@ export interface Api {
46
46
  api_version: string;
47
47
  available_api_versions: ApiVer | ApiVer[];
48
48
  available_endpoints: string[];
49
- entry_types_by_format: {};
49
+ entry_types_by_format: Record<string, unknown>;
50
50
  formats: string[];
51
51
  };
52
52
  }
@@ -61,6 +61,7 @@ export interface Provider {
61
61
  homepage?: string | null;
62
62
  link_type?: string;
63
63
  query_limits?: number[];
64
+ api_version?: string;
64
65
  };
65
66
  }
66
67
 
package/tsconfig.json CHANGED
@@ -11,6 +11,7 @@
11
11
  "noImplicitReturns": true,
12
12
  "noUnusedLocals": true,
13
13
  "noUnusedParameters": true,
14
+ "resolveJsonModule": true,
14
15
  "removeComments": true,
15
16
  "noLib": false,
16
17
  "moduleResolution": "node",
package/tslint.json DELETED
@@ -1,52 +0,0 @@
1
- {
2
- "extends": [
3
- "tslint:recommended",
4
- "tslint-eslint-rules"
5
- ],
6
- "defaultSeverity": "warning",
7
- "jsRules": {},
8
- "rules": {
9
- "curly": [
10
- true,
11
- "ignore-same-line"
12
- ],
13
- "interface-name": [
14
- true,
15
- "never-prefix"
16
- ],
17
- "max-line-length": [
18
- true,
19
- 180
20
- ],
21
- "object-literal-sort-keys": false,
22
- "trailing-comma": [
23
- true,
24
- {
25
- "multiline": "never",
26
- "singleline": "never"
27
- }
28
- ],
29
- "arrow-parens": false,
30
- "member-access": [
31
- true,
32
- "no-public"
33
- ],
34
- "eofline": false,
35
- "whitespace": [
36
- false,
37
- "check-module"
38
- ],
39
- "no-angle-bracket-type-assertion": false,
40
- "ordered-imports": false,
41
- "quotemark": [
42
- true,
43
- "single",
44
- "avoid-escape"
45
- ],
46
- "object-curly-spacing": [
47
- true,
48
- "always"
49
- ]
50
- },
51
- "rulesDirectory": []
52
- }