Convert query parameters from API urls to MongoDB queries !
Project description
MongoDBQueriesManager
Convert query parameters from API urls to MongoDB queries !
This project was inspired by api-query-params (JS Library).
Features:
- Powerful: Supports most of MongoDB operators ($in, $regexp, ...) and features (nested objects, type casting, projection, range filter...)
- Agnostic: Works with any web frameworks (Flask, Sanic, AIOHTTP, Django ...) and/or MongoDB libraries (pymongo, motor, ...)
- Simple: ~500 LOC, Python typing
- Tested: 100% code coverage
Installation:
⚠️ In version 1.0.0 dateparser is an extra dependencies
pip install mongo-queries-manager
pip install mongo-queries-manager['dateparser']
# OR
pipenv install mongo-queries-manager
pipenv install mongo-queries-manager['dateparser']
# OR
poetry add mongo-queries-manager
poetry add mongo-queries-manager['dateparser']
# OR
uv add mongo-queries-manager
uv add mongo-queries-manager --optional dateparser
Usages:
Api
mqm(string_query: str, blacklist: Optional[List[str]] = None, casters: Optional[Dict[str, Callable]] = None, populate: bool = False) -> Dict[str, Any]:
Description
Converts string_query into a MongoDB query dict.
Arguments
string_query: query string of the requested API URL (ie,frist_name=John&limit=10), Works with url encoded. [required]casters: Custom caster dict, used to define custom type (ie,casters={'string': str}/price=string(5.5)->{'price': '5'}) [optional]blacklist: Custom blacklist word, used to ignore specific value from query (ie,blacklist=[where]/company=id,where=43.60,1.44,->{'company': 'id'}) [optional]populate: A boolean value, used to activate the population logic (add a population field into returned dict)
Returns
The resulting dictionary contains the following properties:
filter: Contains the query criteria.projection: Contains the query projectionsort: Contains the sort criteria (cursor modifiers).skip: Contains the skip criteria (cursor modifiers).limit: Contains the limit criteria (cursor modifiers).population: Contains the population criteria. (Only when populate arg is true. To use this population list, a manual implementation is required)
Exception
In case of error the following exception was raised:
MongoDBQueriesManagerBaseError: Base MongoDBQueriesManager errors.SkipError: Raised when skip is negative / bad value.LimitError: Raised when limit is negative / bad value.ListOperatorError: Raised list operator was not possible.FilterError: Raised when parse filter method fail to find a valid match.TextOperatorError: Raised when parse text operator contain an empty string.CustomCasterFail: Raised when a custom cast fail.ProjectionError: Raised when projection json is invalid.LogicalPopulationError: Raised when method fail to find logical population item.LogicalSubPopulationError: Raised when method fail to find logical sub population item.
Examples:
Simple demo
from mongo_queries_manager import mqm
mongodb_query = mqm(string_query="status=sent&price>=5.6&active=true×tamp>"
"2016-01-01&author.firstName=/john/i&limit=100&skip=50&sort=-timestamp&fields=-_id,-created_at")
# {
# 'filter':
# {
# 'status': 'sent',
# 'price': {'$gte': 5.6},
# 'active': True,
# 'timestamp': {'$gt': datetime.datetime(2016, 1, 1, 0, 0)},
# 'author.firstName': re.compile('/john/i')
# },
# 'projection': {'_id': 0, 'created_at': 0},
# 'sort': [('timestamp', -1)],
# 'skip': 50,
# 'limit': 100
# }
Examples with PyMongo
from typing import Dict, Any
from pymongo import MongoClient
from pymongo.collection import Collection
from pymongo.database import Database
from mongo_queries_manager import mqm
client: MongoClient = MongoClient('localhost', 27017)
db: Database = client['test-database']
collection: Collection = db['test-collection']
mongodb_query: Dict[str, Any] = mqm(string_query="status=sent&toto=true×tamp>2016-01-01&"
"author.firstName=/john/i&limit=100&skip=50&sort=-timestamp")
result = collection.find(**mongodb_query)
Supported features
Filter operators:
| MongoDB | URI | Example | Result |
|---|---|---|---|
$eq |
key=val |
type=public |
{'filter': {'type': 'public'}} |
$gt |
key>val |
count>5 |
{'filter': {'count': {'$gt': 5}}} |
$gte |
key>=val |
rating>=9.5 |
{'filter': {'rating': {'$gte': 9.5}}} |
$lt |
key<val |
createdAt<2016-01-01 |
{'filter': {'createdAt': {'$lt': datetime.datetime(2016, 1, 1, 0, 0)}}} |
$lte |
key<=val |
score<=-5 |
{'filter': {'score': {'$lte': -5}}} |
$ne |
key!=val |
status!=success |
{'filter': {'status': {'$ne': 'success'}}} |
$in |
key=val1,val2 |
country=GB,US |
{'filter': {'country': {'$in': ['GB', 'US']}}} |
$nin |
key!=val1,val2 |
lang!=fr,en |
{'filter': {'lang': {'$nin': ['fr', 'en']}}} |
$exists |
key |
phone |
{'filter': {'phone': {'$exists': True}}} |
$exists |
!key |
!email |
{'filter': {'email': {'$exists': False}}} |
$regex |
key=/value/<opts> |
email=/@gmail\.com$/i |
{'filter': {'email': re.compile('/@gmail.com$/i')}} |
$regex |
key!=/value/<opts> |
phone!=/^06/ |
{'filter': {'phone': { '$not': re.compile('/^06/')}}} |
$text |
$text=val |
$text=toto -java |
{'filter': {'$text': { '$search': 'toto -java'}}} |
$text |
$text=val |
$text="toto" |
{'filter': {'$text': { '$search': '"toto"'}}} |
Skip / Limit operators:
- Default operator keys are
skipandlimit. - Used to limit the number of records returned by the query (pagination, result limitation, ...).
- Support empty value (ie,
...&skip=&.../...&limit=&...).
from typing import Dict, Any
from mongo_queries_manager import mqm
mongodb_query: Dict[str, Any] = mqm(string_query="skip=50&limit=50")
# {
# 'filter': {},
# 'sort': None,
# 'projection': None,
# 'skip': 50,
# 'limit': 50
# }
mongodb_query: Dict[str, Any] = mqm(string_query="skip=&limit=")
# {
# 'filter': {},
# 'sort': None,
# 'projection': None,
# 'skip': 0,
# 'limit': 0
# }
Sort operator:
- Used to sort returned records.
- Default operator key is
sort. - Support empty value (ie,
...&sort=&...). - Sort accepts a comma-separated list of fields.
- Default behavior is to sort in ascending order.
- Use
-prefixes to sort in descending order, use+prefixes to sort in ascending order.
from typing import Dict, Any
from mongo_queries_manager import mqm
mongodb_query: Dict[str, Any] = mqm(string_query="sort=created_at,-_id,+price")
#{
# 'filter': {},
# 'sort': [('created_at', 1), ('_id', -1), ('price', 1)],
# 'projection': None,
# 'skip': 0,
# 'limit': 0
#}
Projection operator:
- Useful to limit fields to return in each records.
- It accepts a comma-separated list of fields. Default behavior is to specify fields to return. Use - prefixes to return all fields except some specific fields.
- Due to a MongoDB limitation, you cannot combine inclusion and exclusion semantics in a single projection with the exception of the _id field.
- It also accepts JSON string to use more powerful projection operators ($, $elemMatch or $slice)
from typing import Dict, Any
from mongo_queries_manager import mqm
mongodb_query: Dict[str, Any] = mqm(string_query="fields=-_id,-price")
#{
# 'filter': {},
# 'sort': None,
# 'projection': {'_id': 0, 'price': 0},
# 'skip': 0,
# 'limit': 0
#}
mongodb_query: Dict[str, Any] = mqm(string_query="fields=_id,price")
#{
# 'filter': {},
# 'sort': None,
# 'projection': {'_id': 1, 'price': 1},
# 'skip': 0,
# 'limit': 0
#}
mongodb_query: Dict[str, Any] = mqm(
string_query='fields={"games": {"$elemMatch":{"score": {"$gt": 5}}}},joined,lastLogin')
#{
# 'filter': {},
# 'sort': None,
# 'projection': {'games': {'$elemMatch': {'score': {'$gt': 5}}}, 'joined': 1, 'lastLogin': 1}},
# 'skip': 0,
# 'limit': 0
#}
Range filter:
- Useful to filter fields to return in each records by range.
- No error was handle by this library for range filter
from typing import Dict, Any
from mongo_queries_manager import mqm
query_result: Dict[str, Any] = mqm(string_query="price>5&price<5")
# {
# 'filter':
# {
# 'price': {'$gt': 5.0, '$lt': 5.0},
# },
# 'sort': None,
# 'projection': None,
# 'skip': 0,
# 'limit': 0
# }
Custom caster:
- Used to define custom type
- Optional parameter
from typing import Dict, Any, List
from mongo_queries_manager import mqm
def parse_custom_list(custom_list: str) -> List[str]:
return custom_list.split(';')
query_result: Dict[str, Any] = mqm(string_query="price=string(5)&name=John&in_stock=custom_list(1;2;3;4)&"
"in_stock_string=custom_list(string(1);string(2);string(3);string(4))",
casters={'string': str, 'custom_list': parse_custom_list})
#{
# 'filter':
# {
# 'price': '5',
# 'name': 'John',
# 'in_stock': {'$in': [1, 2, 3, 4]},
# 'in_stock_string': {'$in': ['1', '2', '3', '4']}
# },
# 'sort': None,
# 'projection': None,
# 'skip': 0,
# 'limit': 0
#}
Contribution
Install all development dependencies
# Install dev dependencies
uv sync --locked --all-extras --all-groups --dev
# Run tests
nox
# Pre commit (format / lint / type before commit)
pre-commit install
pre-commit run --all-files
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mongo_queries_manager-1.0.1.tar.gz.
File metadata
- Download URL: mongo_queries_manager-1.0.1.tar.gz
- Upload date:
- Size: 11.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef1192373eb5836d435bc9aa2a8405b4d6c20673c18639ceb8496ac14af9fb81
|
|
| MD5 |
5f39875e5c2bd6de978d4a13a4bf7fb4
|
|
| BLAKE2b-256 |
baee05854e0849fe429c1ac4c2db0db856c708ec68d9b8c597de6d1fa6bc4358
|
File details
Details for the file mongo_queries_manager-1.0.1-py3-none-any.whl.
File metadata
- Download URL: mongo_queries_manager-1.0.1-py3-none-any.whl
- Upload date:
- Size: 12.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
075b2a88f02b77ff13d80c6ee851324c4cf662973bf880bc3425442893ad66d0
|
|
| MD5 |
6171e16270ca22d129b31210c910eea3
|
|
| BLAKE2b-256 |
eea2f4ad94dcf57bcd9583a9a68f918f9822c2c9ff9e740d81777ba82bb03ff2
|