Ejemplo n.º 1
0
    def _request(self, n, k):
        """Constructs the query string for this :class:`Query` object for the
        specified paging limits and then returns the response from the REST API
        as a python object.

        Args:
            n (int): page number of the results to return.
            k (int): number of datasets per page.
        """
        if len(self.responses) == 0:
            #We are making the very first request, finalize the query.
            self.finalize()

        import json
        from six.moves import urllib
        urlopen = urllib.request.urlopen
        url = "{0}{1},{2}".format(server, self.matchbook(),
                                  self._directives(n, k))
        rawresp = urlopen(url).read().decode("utf-8")
        try:
            response = json.loads(rawresp)
        except:  # pragma: no cover
            #We can't easily simulate network failure...
            msg.err("{}\n\n{}".format(url, rawresp))
            return

        #If this is the first request, then save the number of results in the
        #query.
        if len(self.responses) == 0:
            self._N = int(next(iter(response.keys())).split()[-1])
        self.responses[n] = response
Ejemplo n.º 2
0
    def _get_response(url, session=None, page=None):
        """
        Retrieve JSON data from URL with retries.

        Args:
            url (str): url to retrieve
            session (requests.Session): optional, a Session object to
                perform the request
            page (int): optional, metadata holding the page number of the request.
                Useful when this method is called using a thread pool.

        Returns:
            tuple: if page is specified, (is_ok, response, page), otherwise (is_ok, response),
                where `is_ok` is True if the request completed successfully, False otherwise,
                `response` contains the JSON response or the error information if the request
                was unsuccessful, `page` is the page number metadata.
        """
        if not session:
            session = requests.Session()
            retries = Retry(total=5, backoff_factor=10, status_forcelist=[500], connect=0)
            session.mount('http://', HTTPAdapter(max_retries=retries))
        try:
            rawresp = session.get(url)
            is_ok = rawresp.ok
            response = rawresp.json()
        except (ReqConnError, RetryError) as ex:     # pragma: no cover
            is_ok = False
            response = ex.args
            _msg.err("{}\n\n{}".format(url, response))

        if page is not None:
            return is_ok, response, page
        return is_ok, response
Ejemplo n.º 3
0
def _check_input(string):
    """Check if the input string contains invalid string"""
    forbidden_chars = (
        '"',
        "@",
        "\\",
        "~",
        "/",
    )  # characters that will cause LUX crash
    if any([c in string for c in forbidden_chars]):
        msg.err(
            f"Input {string} contains one or more of the forbidden characters: {forbidden_chars}"
        )
        return False
    else:
        return True
Ejemplo n.º 4
0
def cast(atype, keyword, value):
    """Casts the specified value to a python type, using the AFLOW type as a
    reference.

    .. note:: Unfortunately, some of the AFLOW type names are not descriptive or
      unique enough to make general rule casting possible. Instead, we have to
      encode some exceptions directly in this module.
    
    Args:
        atype (str): name of the AFLOW type.
        keyword (str): name of the keyword that the value is associated with.
        value: object (usually a string) to cast into python types.
    """
    if value is None:
        return
    
    castmap = {
        "string": str,
        "strings": _strings,
        "number": _number,
        "numbers": _numbers,
        "forces": _forces,
        "kpoints": _kpoints,
        "positions_cartesian": _forces,
        "positions_fractional": _forces,
        "spind": _numbers,
        "stoich": _stoich,
        "ldau_TLUJ": _ldau_TLUJ,
        "None": lambda v: v,
        None: lambda v: v,
    }

    try:
        if keyword not in exceptions:
            return castmap[atype](value)
        else:
            return castmap[keyword](value)
    except:
        msg.err("Cannot cast {}; unknown format.".format(value))
Ejemplo n.º 5
0
    def set_manual_matchbook(self, matchbook):
        """Statelessly set the matchbook string part of the aflow query
        set the self._matchbook to matchbook and make it final
        matchbook should be a string.

        The method does not enforce type check.
        Use it only when the default keyword method messes up
        """
        if not isinstance(matchbook, str):
            msg.err(
                (f"Manual input query must be a string, not {type(matchbook)}."
                 "The matchbook is not set"))
            self._matchbook = None
            self._final = False
            return self

        if _check_input(matchbook):
            self._matchbook = matchbook
            self._final = True
        else:
            self._matchbook = None

        return self
Ejemplo n.º 6
0
    def filter(self, keyword):
        """Adds a search term to the current filter list. Calling :meth:`filter`
        multiple times will join the final filters together using logical *and*.

        Args:
            keyword (aflow.keywords.Keyword): that encapsulates the AFLUX
              request language logic.

        New version: allowing keyword as a single string containing filters
        """

        if self._final_check():
            self._N = None
            if isinstance(keyword, str):  # normal string
                if _check_input(keyword):
                    self.filters.append(keyword)
            elif hasattr(keyword, "func"):  # Is a sympy symbol
                expr = _expr_to_strings(keyword)
                self.filters.append(expr)
            else:
                msg.err(("Query.filter() takes either "
                         "boolean expression or string,"
                         f" not {type(keyword)}"))
        return self