Commit 0f2fa60c authored by Markus Scheidgen's avatar Markus Scheidgen
Browse files

Merge branch 'bugfixes' into 'v0.9.0'


See merge request !185
parents dd462aa2 22db4462
Pipeline #83208 passed with stages
in 25 minutes and 10 seconds
A simple example used in the NOMAD webinar API tutorial
from nomad.client import ArchiveQuery
query = ArchiveQuery(
'dft.code_name': 'VASP',
'atoms': ['Ti', 'O']
'section_run': {
'section_single_configuration_calculation[-1]': {
'energy_total': '*',
'section_dos': '*'
result = query[0]
# type: ignore
A simple example used in the NOMAD webinar API tutorial
import requests
import json
base_url = ''
# response = requests.get(base_url + '/repo?')
response = requests.get(
base_url + '/repo',
params={'': 'NOMAD webinar', 'per_page': 1})
data = response.json()
upload_id = data['results'][0]['upload_id']
calc_id = data['results'][0]['calc_id']
response = requests.get(
base_url + '/archive/%s/%s' % (upload_id, calc_id))
print(json.dumps(response.json(), indent=2))
......@@ -58,6 +58,8 @@ export function ApiDialog({title, data, onClose, ...dialogProps}) {
<DialogTitle>{title || 'API Code'}</DialogTitle>
<DialogContent classes={{root: classes.content}}>
{ data.code && data.code.repo_url &&
renderCode(<span>URL to this query on the repository API:</span>, data.code.repo_url)}
{ data.code && data.code.curl &&
renderCode(<span>Access the archive as JSON via <i>curl</i>:</span>, data.code.curl)}
{ data.code && data.code.python &&
......@@ -121,6 +121,8 @@ search_model_fields = {
'A list of search results. Each result is a dict with quantitie names as key and '
'values as values'), allow_null=True, skip_none=True),
'code': fields.Nested(api.model('Code', {
'repo_url': fields.String(description=(
'An encoded URL for the search query on the repo api.')),
'python': fields.String(description=(
'A piece of python code snippet which can be executed to reproduce the api result.')),
'curl': fields.String(description=(
......@@ -350,7 +352,7 @@ def _query_api_url(*args, query: Dict[str, Any] = None):
query_string: A dict with query string parameters
url = os.path.join(config.api_url(False), *args)
if query is not None:
if query is not None and len(query) > 0:
url = '%s?%s' % (url, urlencode(query, doseq=True))
return url
......@@ -399,6 +401,20 @@ def _filter_api_query(query):
return result
def query_api_repo_url(query):
Creates an encoded URL string access a search query on the repo api.
query = dict(query)
for to_delete in ['per_page', 'page', 'exclude']:
if to_delete in query:
for key, value in dict(order_by=['upload_time'], order=['-1'], domain=['dft'], owner=['public']).items():
if key in query and query[key] == value:
return _query_api_url('repo', query=query)
def query_api_clientlib(**kwargs):
Creates a string of python code to execute a search query on the archive using
......@@ -35,7 +35,8 @@ from .api import api
from .auth import authenticate
from .common import search_model, calc_route, add_pagination_parameters,\
add_scroll_parameters, add_search_parameters, apply_search_parameters,\
query_api_python, query_api_curl, query_api_clientlib, _search_quantities
query_api_python, query_api_curl, query_api_clientlib, query_api_repo_url, \
ns = api.namespace('repo', description='Access repository metadata.')
......@@ -260,6 +261,7 @@ class RepoCalcsResource(Resource):
if 'statistics' in code_args:
results['code'] = {
'repo_url': query_api_repo_url(code_args),
'curl': query_api_curl(code_args),
'python': query_api_python(code_args),
'clientlib': query_api_clientlib(**code_args)
from locust import HttpUser, task, between
from import chemical_symbols
import random
class QuickstartUser(HttpUser):
wait_time = between(1, 2)
def empty_search(self):
def elements_search(self):
self.client.get("/prod/rae/beta/api/repo/?atoms=%s" % random.choice(chemical_symbols[1:]))
def on_start(self):
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment