How do I search for specific types of computations?#

This notebook introduces you to the basics of connecting to a QCArchive server and retrieving computation results using information like molecule, basis set, method, or other computation details.

You can retrieve results from QCArchive using the get_records method if you know the ID of the computation you’d like to retrieve. However, you can also query the database for computations having specific details using query methods.

import qcportal as ptl

Create a client object and connect to the demo server#

The PortalClient is how you interact with the server, including querying records and submitting computations.

The demo server allows for unauthenticated guest access, so no username/password is necessary to read from the server. However, you will need to log in to submit or modify computations.

# Guest access
client = ptl.PortalClient("https://qcademo.molssi.org")
---------------------------------------------------------------------------
PortalRequestError                        Traceback (most recent call last)
Cell In[2], line 2
      1 # Guest access
----> 2 client = ptl.PortalClient("https://qcademo.molssi.org")

File ~/work/QCFractal/QCFractal/qcportal/qcportal/client.py:150, in PortalClient.__init__(self, address, username, password, verify, show_motd, cache_dir, cache_max_size, memory_cache_key)
    116 def __init__(
    117     self,
    118     address: str,
   (...)
    126     memory_cache_key: Optional[str] = None,
    127 ) -> None:
    128     """
    129     Parameters
    130     ----------
   (...)
    147         Maximum size of the cache directory
    148     """
--> 150     PortalClientBase.__init__(self, address, username, password, verify, show_motd)
    151     self._logger = logging.getLogger("PortalClient")
    152     self.cache = PortalCache(address, cache_dir, cache_max_size)

File ~/work/QCFractal/QCFractal/qcportal/qcportal/client_base.py:156, in PortalClientBase.__init__(self, address, username, password, verify, show_motd)
    153     self._jwt_refresh_exp = None
    155 # Try to connect and pull the server info
--> 156 self.server_info = self.get_server_information()
    157 self.server_name = self.server_info["name"]
    158 self.api_limits = self.server_info["api_limits"]

File ~/work/QCFractal/QCFractal/qcportal/qcportal/client.py:190, in PortalClient.get_server_information(self)
    181 """Request general information about the server
    182 
    183 Returns
   (...)
    186     Server information.
    187 """
    189 # Request the info, and store here for later use
--> 190 return self.make_request("get", "api/v1/information", Dict[str, Any])

File ~/work/QCFractal/QCFractal/qcportal/qcportal/client_base.py:416, in PortalClientBase.make_request(self, method, endpoint, response_model, body_model, url_params_model, body, url_params, allow_retries)
    413 if isinstance(parsed_url_params, pydantic.BaseModel):
    414     parsed_url_params = parsed_url_params.dict()
--> 416 r = self._request(
    417     method, endpoint, body=serialized_body, url_params=parsed_url_params, allow_retries=allow_retries
    418 )
    419 d = deserialize(r.content, r.headers["Content-Type"])
    421 if response_model is None:

File ~/work/QCFractal/QCFractal/qcportal/qcportal/client_base.py:381, in PortalClientBase._request(self, method, endpoint, body, url_params, internal_retry, allow_retries)
    376     except:
    377         # If this error comes from, ie, the web server or something else, then
    378         # we have to use 'reason'
    379         details = {"msg": r.reason}
--> 381     raise PortalRequestError(f"Request failed: {details['msg']}", r.status_code, details)
    383 return r

PortalRequestError: Request failed: Not Found (HTTP status 404)

Connecting with username/password

If you have a username/password, you would include those in the client connection.

client = ptl.PortalClient("https://qcademo.molssi.org", username="YOUR_USERNAME", password="YOUR_PASSWORD")

⚠️Caution⚠️: Always handle credentials with care. Never commit sensitive information like usernames or passwords to public repositories.

Querying Records#

Use the `query_records method`` for general queries. This method allows you to search across all records in the database, regardless of the computation type. Please note that since query_records searches all record types, you can only query fields that are common to all records.

help(client.query_records)

For example, to query for computations created between January 10, 2023 and January 14, 2023, we could do the following.

results = client.query_records(created_after="2023/01/10", created_before="2023/01/14")

Our results from this query will be in something called an iterator. An iterator can be made into a list by casting or used in a for loop.

results_list = list(results)
print(f"Found {len(results_list)} results.")

After the results are retrieved, you can work with the records as shown in the “How do I work with computation records?” tutorial.

Querying by computation details#

If you want to query by computation specifications such as basis set, method, molecule, etc, you will need to use a more specific query methods. For example, if you want to query single point computations, you should use the query_singlepoints method. Documentation for the query_singlepoints method is shown below.

help(client.query_singlepoints)

As shown in the help message above, you can query single points on many different parameters. For example, you might choose to query the database for mp2 calculations using the aug-cc-pvtz basis using the psi4 program. For the sake of demonstration in this notebook, we are limiting the number of results to 5 records.

results = client.query_singlepoints(method="mp2", basis="aug-cc-pvtz", program="psi4", limit=5)

After retrieving the results, we can loop through them and view information about the records.

for record in results:
    print(record.id, record.molecule)