MoleQL
Expressive URL-query to MongoDB query conversion library.
Overview
MoleQL allows your REST APIs or data layers to accept
URL-style query strings (e.g. ?age>30&status=in(active,pending))
and converts them into MongoDB-compatible query dictionaries.
It supports filters, sorting, skip/limit, projection and text search.
Example:
from moleql import parse
query = parse("age>30&country=US&name=/^John/i")
# yields:
# {
# "filter": {"age": {"$gt": 30}, "country": "US", "name": {"$regex": "^John", "$options": "i"}},
# "sort": None,
# "skip": 0,
# "limit": 0,
# "projection": None
# }
✨ Features
- 🧠 Intuitive syntax:
=, !=, <, <=, >, >= - 📋 List operators:
in(...), ... - 🔍 Regex:
/pattern/flags → $regex + $options - 🧾 Pagination:
skip=10, limit=50 - ⚙️ Sorting:
sort=-created_at,name - 🧩 Projection:
fields=name,email,age - 🔠 Text search:
text=free text hereor$text=free text here - 🧱 Type casters:
custom value transformations - 🚫 Blacklist: skip parsing of restricted fields
- 🧪 Tested: full pytest coverage, Ruff linting
🧰 Installation
With uv (recommended):
uv add moleql
pip install moleql
🚀 Quick Start
from moleql import parse
query = parse("age>30&country=US&name=/^John/i")
print(query)
# {
# "filter": {
# "age": {"$gt": 30},
# "country": "US",
# "name": {"$regex": "^John", "$options": "i"}
# },
# "sort": None,
# "skip": 0,
# "limit": 0,
# "projection": None
# }
Extended example
from moleql import parse
query = parse(
"age>=18&status=in(active,pending)"
"&sort=-created_at,name"
"&skip=10&limit=20"
"&fields=name,email,age"
)
Output:
{
"filter": {
"age": {"$gte": 18},
"status": {"$in": ["active", "pending"]}
},
"sort": [("created_at", -1), ("name", 1)],
"skip": 10,
"limit": 20,
"projection": {"name": 1, "email": 1, "age": 1}
}
🔣 Supported Operators
| Expression | Mongo Operator | Example |
|---|---|---|
= |
direct match | age=20 → {"age": 20} |
!= |
$ne |
status!=active |
> / >= |
$gt / $gte |
score>=80 |
< / <= |
$lt / $lte |
price<10 |
in(...) |
$in |
role=in(admin,user) |
!=in(...) |
$nin |
tier!=in(gold,platinum) |
/pattern/flags |
$regex |
name=/^Jo/i |
text= or $text= |
$text |
text=free search text |
fields= |
projection | fields=name,email |
sort= |
sort directive | sort=-created_at,name |
🧱 Quick API Reference
parse(moleql_query: str, blacklist=None, casters=None) -> dict
from moleql import parse
parse("age>25&active=true")
Returns a dictionary with:
filter, sort, skip, limit, projection
moleqularize(moleql_query: str, blacklist=None, casters=None) -> MoleQL
Parse a MoleQL string and return the internal MoleQL object for advanced inspection and debugging.
from moleql import moleqularize
m = moleqularize("age>25")
print(m.mongo_query)
🧩 Custom Casters
You can define custom casters to control type conversions.
from moleql import parse, get_casters
def to_bool(value: str) -> bool:
return value.lower() in ("true", "1", "yes")
custom_casters = {"bool": to_bool}
q = parse("active=bool(true)&age>30", casters=custom_casters)
🧠 Design Philosophy
- Transparency — The query string is readable and reversible.
- Safety — No eval, injection-safe parsing.
- Extensibility — Easy to plug in custom handlers.
- Predictability — Every operator maps 1:1 to Mongo semantics.
- Minimal dependencies — Pure Python, no ODM required.
⚙️ Integration Examples
FastAPI
from fastapi import FastAPI, Request
from moleql import parse
from pymongo import MongoClient
db = MongoClient()["app"]
app = FastAPI()
@app.get("/users")
def list_users(request: Request):
q = parse(request.url.query.lstrip("?"))
return list(db.users.find(q["filter"]))
Flask
from flask import Flask, request, jsonify
from moleql import parse
app = Flask(__name__)
@app.get("/orders")
def orders():
q = parse(request.query_string.decode())
return jsonify(q)
🧪 Testing
Run the full suite using uv:
uv sync --all-extras --dev
uv run pytest -vv --cov=moleql --cov-report=term-missing --cov-fail-under=100
Generate coverage:
uv run pytest --cov=moleql --cov-report=term-missing --cov-fail-under=100
🧹 Code Quality
This repository uses:
- Ruff — Linting + formatting (UP / pyupgrade rules)
- pre-commit — automatic checks
- pytest — testing
- uv — environment & packaging
Set up hooks:
uv run pre-commit install
uv run pre-commit run --all-files
🧭 Roadmap
- [] Add exists(field) and between(a,b) operators
- [] Add optional CLI (moleql "age>20" --as-json)
- [] Extended docs and tutorials
🤝 Contributing
-
Fork this repository
-
Create your feature branch
git checkout -b feat/awesome-change
-
Run formatting and tests
uv run pre-commit run --all-files uv run pytest
-
Commit and push your changes
-
Open a Pull Request 🚀
See CODE_OF_CONDUCT.md for details.
🌟 Acknowledgments
Built and maintained by @OneTesseractInMultiverse Inspired by the need for readable, typed, and safe Mongo queries in API environments.
Metadata
Release files for moleql 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| moleql-0.2.0.tar.gz | 12.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| moleql-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 31.1 kB
Release files / moleql-0.2.0.tar.gz
| Download URL | moleql-0.2.0.tar.gz |
|---|---|
| Size | 12.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e1bea84086e432a7f295473fa0c5ebb3d6806d29c3be6cb1d0f390dac9e2a617
|
|
BLAKE2b-256 checksum How to use checksums |
ac3ff85e5cac78f9bf7a01c29c45db640d449f0f1ab831f7accd184abbfe136c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 11, 2026.
Transparency logRelease files / moleql-0.2.0-py3-none-any.whl
| Download URL | moleql-0.2.0-py3-none-any.whl |
|---|---|
| Size | 18.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dae13a567f61834c7a8c31725adbe7725f0935817502e93fdc4bbc039b960cd7
|
|
BLAKE2b-256 checksum How to use checksums |
cadceed2cbbf2d4cc113ac8fd3b1065548a4c37f8d887b1beaf05af2f0a185bb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 11, 2026.
Transparency log