monquery

A library for HTTP query string to MongoDB queries translation


Keywords
mongodb, utility, http, mongo, pymongo, python, python3, rest-api
License
MIT
Install
pip install monquery==0.3.0

Documentation

Build Status codecov Code style: black

Monquery

A small toolkit enabling easier declarative approach to declaring read API with MongoDB backend with rich filtering query parameters and minimum hustle.

It's framework-agnostic which means its role boils down to translating HTTP request query string into a valid MongoDB query.

Installation

pip install monquery

How it works

Filtering:

from urllib.parse import parse_qs
from monquery import (
    FilterSimple, ParamEq, parse_int, parse_string, parse_datetime_iso, ParamMax, ParamMin
)

FilterSimple(
    [
        ParamEq("bar", parse_string, multi=False),
        ParamEq("baz", parse_int, multi=False),
        ParamMax("foo[max]", parse_datetime_iso, target_field="foo"),
        ParamMin("foo[min]", parse_datetime_iso, target_field="foo"),
    ]
).from_query(
    parse_qs("foo[max]=2022-05-06T20:35:14.991282&bar=hello there&baz=4")
)

# returns the filter and error (which is None in this case meaning that everything is OK): 
# (
#    {
#        "bar": {"$eq": "hello there"},
#        "baz": {"$eq": 4},
#        "foo": {"$lt": datetime(2022, 5, 6, 20, 35, 14, 991282)},
#    },
#    None,
# )
#

Sorting:

from urllib.parse import parse_qs
from monquery import (
    Sorting, SortingOption, 
)

Sorting(
    options=[
        SortingOption("foo"),
        SortingOption("-foo", field="foo", direction=-1),
        SortingOption("bar"),
        SortingOption("-bar", field="bar", direction=-1),
        SortingOption("baz", direction=-1),
    ]
).from_query(parse_qs("sort=foo"))

#   Returns:
#   (SortingOption("foo"), None)

Pagination:

from urllib.parse import parse_qs
from monquery import PaginationBasic

PaginationBasic().from_query(parse_qs("skip=14&limit=32")) 

#   returns:
#    (
#        Pg(skip=14, limit=32),
#        None,
#    )

Utility function to bind it all together wtih a pymongo collection like this:

import pymongo
from urllib.parse import parse_qs

from monquery import (
    pymongo_find,
    FilterSimple,
    ParamEq,
    PaginationBasic,
    parse_float,
    parse_int,
    Sorting,
    SortingOption,
)
from pymongo import MongoClient, ASCENDING, DESCENDING

client = MongoClient("your-connection-string-or-whatever")
coll = client["your-database-name"]["your-collection-name"]

cursor, error = pymongo_find(
    coll,
    fltr=FilterSimple([ParamEq("foo", parse_float), ParamEq("bar", parse_int)]),
    pg=PaginationBasic(),
    sorting=Sorting([SortingOption("foo", field="foo", direction=ASCENDING),
                     SortingOption("-foo", field="foo", direction=DESCENDING)]),
    query=parse_qs("foo=234.43&bar=68452"),
)

# Returns a pymongo cursor and optional error, if one occurred.

Don't be shy to look into the unit tests and source code if in doubt.

There's also a neat demo app here.