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 +17 -0
- package/README.md +11 -9
- package/dist/index.js +82 -25
- package/dist/index.mjs +80 -23
- package/dist/prefetched.json +1 -1
- package/dist/providers.json +1 -1
- package/dist/{index.d.ts → src/index.d.ts} +17 -3
- package/dist/{types.d.ts → src/types.d.ts} +2 -1
- package/dist/{utils.d.ts → src/utils.d.ts} +0 -0
- package/package.json +16 -5
- package/prefetch.js +33 -17
- package/rollup.config.js +4 -0
- package/src/index.ts +74 -22
- package/src/types.ts +2 -1
- package/tsconfig.json +1 -0
- package/tslint.json +0 -52
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
92
|
-
const pageOffset =
|
|
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(
|
|
115
|
-
const results =
|
|
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
|
-
|
|
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
|
|
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
|
|
88
|
-
const pageOffset =
|
|
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(
|
|
111
|
-
const results =
|
|
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();
|
package/dist/prefetched.json
CHANGED
|
@@ -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}}]}}
|
package/dist/providers.json
CHANGED
|
@@ -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
|
|
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
|
|
16
|
-
|
|
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?:
|
|
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
|
+
"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": "
|
|
11
|
-
"lint:fix": "
|
|
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
|
-
"
|
|
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
|
-
|
|
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(
|
|
32
|
+
const source = Object.keys(providers).sort().reduce(
|
|
25
33
|
(obj, key) => {
|
|
26
|
-
obj[key] =
|
|
34
|
+
obj[key] = providers[key];
|
|
27
35
|
return obj;
|
|
28
36
|
}, {});
|
|
29
37
|
|
|
30
|
-
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
|
|
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
|
|
8
|
-
private corsProxyUrl
|
|
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
|
|
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
|
|
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
|
|
77
|
-
const pageOffset =
|
|
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
|
|
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(
|
|
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 =
|
|
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
|
|
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
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
|
-
}
|