Beispiel #1
0
def cached_part(query, cache=None):
    """Get cached part of the query.
    Use either supplied cache object or global cache object (default).
    In the process, query is into two parts: the beginning of the query
    and the remainder. Function tries to find longest possible beginning of the query
    which is cached, then returns the cached state and the remainder of the query.
    (query == state.query + "/" + remainder)
    """
    if cache is None:
        cache = get_cache()

    if isinstance(
        cache, NoCache
    ):  # Just an optimization - to avoid looping over all query splits
        return State(), encode(decode(query))

    for key, remainder in all_splits(query):
        if key == "":
            return State(), remainder
        if cache.contains(key):
            state = cache.get(key)
            if state is None:
                continue
            return state, remainder

    # Should never get here, but this is a sensible default:
    return State(), encode(decode(query))
Beispiel #2
0
def qtsplit_df(state, *columns):
    """Quick/query split of dataframe by columns (version expecting a first row with tags)
    Creates a dataframe with unique (combinations of) value from supplied columns and queries
    to obtain the corresponding filtered dataframes from the original dataframe.
    Resulting queries are put in query column. Name of the query column
    can be overriden by query_column state variable.
    """
    df = state.get()
    tags = df.iloc[0]
    df = df.iloc[1:]

    if len(columns) == 1:
        keys = [(x,) for x in sorted(df.groupby(by=list(columns)).groups.keys())]
    else:
        keys = sorted(df.groupby(by=list(columns)).groups.keys())

    query_column = state.vars.get("query_column")
    if query_column is None:
        query_column = "query"

    sdf = pd.DataFrame(columns=list(columns) + [query_column])
    sdf = sdf.append({c: tags[c] for c in columns}, ignore_index=True)
    data = []
    ql = decode(state.query)
    for row in keys:
        pairs = list(zip(columns, row))
        d = dict(pairs)
        query = encode(ql + [["teq"] + [str(x) for p in pairs for x in p]])
        d[query_column] = query
        sdf = sdf.append(d, ignore_index=True)

    return state.with_data(sdf)
Beispiel #3
0
def build():
    """Build a query from a posted decoded query (list of lists of strings).
    Result is a dictionary with encoded query and link.
    """
    from liquer.parser import encode
    query = encode(request.get_json(force=True)["ql"])
    link = get_vars().get("server", "http://localhost") + \
        get_vars().get("api_path", "/q/") + query
    return jsonify(dict(query=query, link=link, message="OK", status="OK"))
Beispiel #4
0
    def post(self):
        from liquer.parser import encode

        query = encode(json.loads(self.request.body)["ql"])
        link = (get_vars().get("server", "http://localhost") +
                get_vars().get("api_path", "/q/") + query)
        self.write(
            json.dumps(dict(query=query, link=link, message="OK",
                            status="OK")))
Beispiel #5
0
    def evaluate_command_old(self, state, qcommand: list):
        if not state.is_volatile():
            state = state.clone()
        command_name = qcommand[0]
        ns, command, metadata = self.resolve_command(state, command_name)
        if command is None:
            print(f"Unknown command: {command_name}")
            return state.with_data(None).log_error(
                message=f"Unknown command: {command_name}")
        else:
            try:
                state = command(state, *qcommand[1:])
            except Exception as e:
                traceback.print_exc()
                state.log_exception(message=str(e),
                                    traceback=traceback.format_exc())
                state.exception = e
        arguments = getattr(state, "arguments", None)
        state.metadata["commands"].append(qcommand)
        state.metadata["extended_commands"].append(
            dict(
                command_name=command_name,
                ns=ns,
                qcommand=qcommand,
                command_metadata=metadata._asdict(),
                arguments=arguments,
            ))
        state.query = encode(state.metadata["commands"])
        state.metadata["attributes"] = {
            key: value
            for key, value in state.metadata["attributes"].items()
            if key[0].isupper()
        }
        if metadata is not None:
            state.metadata["attributes"].update(metadata.attributes)

        return state
Beispiel #6
0
def gui(state):
    import liquer.parser as p
    d = state.as_dict()
    c = d["extended_commands"][-1]
    m = c["command_metadata"]
    ns = c['ns']
    name = m['name']
    title = d["attributes"].get("title", m["label"])
    help_link = (d["vars"].get("server", "http://localhost") +
                 d["vars"].get("api_path", "/q/") +
                 f"ns-meta/help-{name}-{ns}/help.html")
    query_start = p.encode(d["commands"][:-1] + [[d["commands"][-1][0]]])
    html = f"""
<!DOCTYPE html>
<html>

<head>
    <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
    <title>{title}</title>
</head>
<body>
    <div id="app" color="indigo">
        <v-app>
            <v-content>
                <v-container class="fill-height" fluid>
                <v-card width="100%">
                    <v-toolbar color="secondary" dark>
                        <v-toolbar-title>{title}</v-toolbar-title>
                        <v-spacer></v-spacer>
                        <v-btn href="{help_link}">Help</v-btn>
                    </v-toolbar>
                    <v-content>
                    <v-container>
"""
    for value, a in c["arguments"]:
        html += f"""<v-row><v-text-field v-model="{a['name']}" label="{a['label']}"></v-text-field></v-row>
        """
    html += """<v-row><b>Query:</b>{{_query}}</v-row>
        """
    html += """<v-row><b>Link:</b><a :href="_link">{{_link}}</a></v-row>
        """
    html += """<v-row><v-spacer></v-spacer><v-btn :href="_link">Execute</v-btn></v-row>
        """

    html += """       </v-container>
                    <v-content>
                </v-card>
                </v-container>
            </v-content>
        </v-app>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.js"></script>
    <script>
    new Vue({
      el: '#app',
      data:{
"""
    qq = ""
    for value, a in c["arguments"]:
        if isinstance(value, list):
            value = "-".join(p.encode_token(value))
        html += f"""{a['name']}:"{value}",
        """
        qq += f"+'-'+this.{a['name']}"
    html += """
      },
      computed:{
        _query: function(){
            return '%s'%s;
        },          
        _link: function(){
            return '%s'+this._query;
        }          
      },
      vuetify: new Vuetify(),
    })    
    </script>
</body>

</html>    
    """ % (query_start, qq, d["vars"].get("server", "http://localhost") +
           d["vars"].get("api_path", "/q/"))
    return state.with_data(html).with_filename("gui.html")
Beispiel #7
0
# Make it run from the examples directory
import sys
sys.path.append("..")

from liquer import *
from liquer.parser import encode, encode_token
import liquer.ext.lq_pandas

url = "https://raw.githubusercontent.com/orest-d/liquer/master/tests/test.csv"

query = encode([["df_from", url]])
print(f"Query: {query}")
print(evaluate(query).get())

query = "df_from-" + encode_token(url)
print(f"Query: {query}")
print(evaluate(query).get())

query = f"{query}/eq-a-3"
print(f"Query: {query}")
print(evaluate(query).get())