#!/usr/bin/env python # coding: utf-8 # ### Preparations # Import `requests` library for http request and define API endpoints # In[1]: import requests import pprint import sys import ase.io try:# catch module change from Python2->3 import io except: import StringIO as io API = 'http://api.catalysis-hub.org' SEARCH_ENDPOINT = API + '/apps/prototypeSearch/facet_search/' PROTOTYPE_ENDPOINT = API + '/apps/prototypeSearch/prototype/' STRUCTURE_ENDPOINT = API + '/apps/prototypeSearch/get_structure/' # The prototype App uses 3 API endpoints for searching and retrieving structures. Below we go through a practical example of how to use them together. The `request` is a very user friendly module to make HTTP requests from python. If you don't have it installed, you can change that with `pip install requests --user` # ### Search # Let's make use of the facet_search API to find all materials with a given composition # In[2]: r = requests.post(SEARCH_ENDPOINT, json={ "search_terms": "stoichiometry:AB2", "limit": 1000, }) # In[3]: len(r.json()['prototypes']) # We can learn about other possible arguments by inspecting the 'input' field of the result # In[4]: r.json()['input'] # To see how many structures of this composition are in each repository, we look at the repositories facet. # In[5]: r.json()['repositories'] # The facet lists are ordered by frequency by default. There are of course all the other facets, that are also in the GUI. # In[6]: r.json().keys() # ### Filter # To narrow down the result, we look, e.g. only at the AB2 structures in OQMD # In[7]: r = requests.post(SEARCH_ENDPOINT, json={ "search_terms": "stoichiometry:AB2 repository:OQMD", "limit": 1000, }) # In[8]: r.json() # ### Prototypes # Some prototypes are apparently more frequent than others. So let's have a look at the structures in the `AB2_a_d_191` prototype. To this end we use the prototype API. # In[9]: r = requests.post(PROTOTYPE_ENDPOINT, json={ "prototype": "AB2_a_d_191", "search_terms": "repository:OQMD" }) # In[10]: len(r.json()['prototypes']) # ### Structures # So, let's say we want to do some specific manipulation on structures. To this end it will be handy to turn it into ASE atoms objects. # In[11]: structures = [] for prototype in r.json()['prototypes'][:10]: sys.stdout.write('.') r_structure = requests.post(STRUCTURE_ENDPOINT, json=prototype) cif = r_structure.json()['structure'] with io.StringIO() as cif_file: cif_file.write(cif) cif_file.seek(0) structures.append( ase.io.read(cif_file, format='cif') ) # In[12]: structures # Voila! # # Ok, should be admitted, that doing `n` HTTP round trips for `n` structures is not ideal. We are working on that.