Catalog PyPI
PACKAGE EXPLORERView in registry

aggify

PyPI

Async-first MongoDB ODM with a Django-style API: QuerySets, aggregation pipelines, FastAPI/gRPC/Django integrations.

aggregationasyncdjangofastapimongodbodmormpymongo
Versions collected1
Direct dependencies6From release 1.0.0
Last observed21 Oct, 09:03 UTC

README

Version 1.0.0 documentation

Aggify

Async-first MongoDB ODM with a Django-style API - for Django, FastAPI, gRPC and plain Python

Package version Downloads Supported Python versions Coverage License Telegram

Aggify 1.0 is a complete rewrite: no MongoEngine, native async/await on pymongo's AsyncMongoClient, an API you already know from the Django ORM, and aggregation pipelines that fit on one line.

import aggify
from aggify import Document, StringField, DecimalField, ReferenceField, Sum, Count

aggify.connect("mongodb://localhost:27017/shop")

class Customer(Document):
    name = StringField(required=True)
    country = StringField(max_length=2)

class Order(Document):
    customer = ReferenceField(Customer)
    status = StringField(choices=["new", "paid"], default="new")
    total = DecimalField()

best = await (
    Order.objects.filter(status="paid", customer__country="DE")      # $lookup + $unwind + $match
    .values("customer__name")
    .annotate(revenue=Sum("total"), orders=Count())                  # $group
    .filter(orders__gte=3)                                           # HAVING
    .order_by("-revenue")[:10]                                       # $sort + $limit
    .alist()
)

Highlights

  • Sync and async - every I/O method has an a-twin (aget, alist, asave, acount, aupdate, ...); one async client per event loop, so it is safe in FastAPI, grpc.aio, Django's async_to_sync and pytest-asyncio.
  • Django-style - Model.objects, Q, F, annotate, aggregate, values, select_related, get_or_create, signals, managers, DoesNotExist, pagination-ready querysets.
  • Complex queries, short - automatic joins (owner__country="DE"), values().annotate() grouping, conditional aggregates (Sum("x", filter=Q(...))), window functions, $facet, $bucket, $graphLookup, sub-pipeline $lookup, array operators, atomic expression updates. See the cookbook.
  • Framework-agnostic integrations - pip install "aggify[fastapi|grpc|django|pydantic]". Pydantic schemas from documents, FastAPI lifespan/errors/pagination, gRPC status mapping, Django app/forms/shortcuts/middleware, and an ObjectIdField to link Django ORM models to Mongo documents.
  • Secure by default - typed fields stop operator injection ({"$ne": ""}), regex lookups are escaped, server-side JavaScript is blocked, field names validated, strict constructors, resource limits, masked credentials.
  • Efficient - save() sends only changed fields, optional optimistic locking, only()/defer()/values(), streaming iterators, bulk operations.
  • Well tested - 470+ tests: unit, integration against a real replica set, differential property tests (random Q trees vs. a Python reference), FastAPI/gRPC/Django end-to-end tests, Python 3.9-3.13.

Install

pip install aggify                       # core (pymongo >= 4.13)
pip install "aggify[fastapi]"            # + pydantic / fastapi helpers
pip install "aggify[django]" "aggify[grpc]" "aggify[all]"

A tour

# models: typed fields, embedded documents, references, indexes
class Account(Document):
    username = StringField(required=True, unique=True)
    tags = ListField(StringField())
    address = EmbeddedField(Address)
    created_at = DateTimeField(auto_now_add=True)
    class Meta:
        ordering = ["username"]
        indexes = [Index("tags")]

# CRUD - only changed fields are written
acc = await Account.objects.acreate(username="ali", tags=["vip"])
acc.address = Address(city="Tehran")
await acc.asave()                               # {"$set": {"address": {...}}}

# querying
Account.objects.filter(Q(tags="vip") | Q(address__city__istartswith="te"), ~Q(banned=True))
Account.objects.filter(age__gt=F("score") * 10).only("username")[:20]

# atomic updates, including server-side expressions
Account.objects.filter(pk=acc.pk).update(inc__logins=1, push__tags="beta")
Product.objects.update(price=Round(F("price") * Value(1.1), 2))

# transactions (replica set)
async with aggify.atransaction():
    await Order.objects.acreate(...)
    await Product.objects.filter(pk=pid).aupdate(inc__stock=-1)

# the compiled query is always inspectable
Account.objects.filter(address__city="Tehran").query

Need a stage a queryset does not have? The immutable pipeline builder is one call away:

from aggify import Aggify
Aggify(Order).filter(status="paid").facet(
    by_country=Aggify(Order).group("customer__country", n=Count()),
    page=[{"$limit": 20}],
).execute()

Documentation

Full documentation lives in docs/ (build with make docs): quickstart - models - querying - pipelines - cookbook - security - testing - Django - FastAPI - gRPC - MongoEngine migration - upgrading from 0.x - فارسی.

Development

make install && make mongo && make test      # needs Docker for the throw-away MongoDB replica set

See CONTRIBUTING.md. Security reports: SECURITY.md.

Downloads & popularity

76downloads
1-day window · source-reported counts21 Oct 2026
8944.50
2026-07-24: 6 · observed 2026-10-22T12:12:04.9079092Z · period 2026-07-24–2026-07-242026-07-25: 3 · observed 2026-10-22T12:12:04.9079092Z · period 2026-07-25–2026-07-252026-07-26: 1 · observed 2026-10-22T12:12:04.9079092Z · period 2026-07-26–2026-07-262026-07-27: 2 · observed 2026-10-22T12:12:04.9079092Z · period 2026-07-27–2026-07-272026-07-28: 1 · observed 2026-10-22T12:12:04.9079092Z · period 2026-07-28–2026-07-282026-07-29: 1 · observed 2026-10-22T12:12:04.9079092Z · period 2026-07-29–2026-07-292026-07-30: 2 · observed 2026-10-22T12:12:04.9079092Z · period 2026-07-30–2026-07-302026-08-01: 2 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-01–2026-08-012026-08-02: 3 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-02–2026-08-022026-08-03: 1 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-03–2026-08-032026-08-04: 3 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-04–2026-08-042026-08-06: 1 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-06–2026-08-062026-08-07: 1 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-07–2026-08-072026-08-09: 11 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-09–2026-08-092026-08-13: 1 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-13–2026-08-132026-08-14: 2 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-14–2026-08-142026-08-15: 2 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-15–2026-08-152026-08-17: 2 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-17–2026-08-172026-08-18: 10 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-18–2026-08-182026-08-19: 1 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-19–2026-08-192026-08-20: 3 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-20–2026-08-202026-08-21: 2 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-21–2026-08-212026-08-23: 4 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-23–2026-08-232026-08-24: 7 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-24–2026-08-242026-08-25: 1 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-25–2026-08-252026-08-27: 9 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-27–2026-08-272026-08-28: 7 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-28–2026-08-282026-08-31: 2 · observed 2026-10-22T12:12:04.9079092Z · period 2026-08-31–2026-08-312026-09-01: 3 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-01–2026-09-012026-09-03: 1 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-03–2026-09-032026-09-04: 1 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-04–2026-09-042026-09-05: 1 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-05–2026-09-052026-09-07: 2 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-07–2026-09-072026-09-08: 2 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-08–2026-09-082026-09-09: 2 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-09–2026-09-092026-09-10: 2 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-10–2026-09-102026-09-11: 1 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-11–2026-09-112026-09-12: 6 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-12–2026-09-122026-09-13: 7 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-13–2026-09-132026-09-14: 10 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-14–2026-09-142026-09-15: 14 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-15–2026-09-152026-09-16: 20 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-16–2026-09-162026-09-17: 4 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-17–2026-09-172026-09-18: 2 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-18–2026-09-182026-09-21: 17 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-21–2026-09-212026-09-22: 6 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-22–2026-09-222026-09-23: 3 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-23–2026-09-232026-09-24: 5 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-24–2026-09-242026-09-25: 1 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-25–2026-09-252026-09-26: 40 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-26–2026-09-262026-09-27: 13 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-27–2026-09-272026-09-28: 3 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-28–2026-09-282026-09-29: 5 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-29–2026-09-292026-09-30: 5 · observed 2026-10-22T12:12:04.9079092Z · period 2026-09-30–2026-09-302026-10-01: 3 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-01–2026-10-012026-10-02: 3 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-02–2026-10-022026-10-03: 3 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-03–2026-10-032026-10-04: 14 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-04–2026-10-042026-10-05: 4 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-05–2026-10-052026-10-06: 1 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-06–2026-10-062026-10-07: 5 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-07–2026-10-072026-10-08: 4 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-08–2026-10-082026-10-09: 1 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-09–2026-10-092026-10-10: 5 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-10–2026-10-102026-10-11: 19 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-11–2026-10-112026-10-12: 3 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-12–2026-10-122026-10-13: 3 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-13–2026-10-132026-10-14: 40 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-14–2026-10-142026-10-15: 2 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-15–2026-10-152026-10-17: 89 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-17–2026-10-172026-10-18: 13 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-18–2026-10-182026-10-19: 2 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-19–2026-10-192026-10-20: 62 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-20–2026-10-202026-10-21: 76 · observed 2026-10-22T12:12:04.9079092Z · period 2026-10-21–2026-10-21
24 Jul21 Oct

pypistats · 74 observations shown. Missing days are unknown. Source category: overall: without mirrors.

View observed values
Date / source periodValueObserved at
2026-10-21 – 2026-10-21762026-10-22T12:12:04.9079092Z
2026-10-20 – 2026-10-20622026-10-22T12:12:04.9079092Z
2026-10-19 – 2026-10-1922026-10-22T12:12:04.9079092Z
2026-10-18 – 2026-10-18132026-10-22T12:12:04.9079092Z
2026-10-17 – 2026-10-17892026-10-22T12:12:04.9079092Z
2026-10-15 – 2026-10-1522026-10-22T12:12:04.9079092Z
2026-10-14 – 2026-10-14402026-10-22T12:12:04.9079092Z
2026-10-13 – 2026-10-1332026-10-22T12:12:04.9079092Z
2026-10-12 – 2026-10-1232026-10-22T12:12:04.9079092Z
2026-10-11 – 2026-10-11192026-10-22T12:12:04.9079092Z
2026-10-10 – 2026-10-1052026-10-22T12:12:04.9079092Z
2026-10-09 – 2026-10-0912026-10-22T12:12:04.9079092Z
2026-10-08 – 2026-10-0842026-10-22T12:12:04.9079092Z
2026-10-07 – 2026-10-0752026-10-22T12:12:04.9079092Z
2026-10-06 – 2026-10-0612026-10-22T12:12:04.9079092Z
2026-10-05 – 2026-10-0542026-10-22T12:12:04.9079092Z
2026-10-04 – 2026-10-04142026-10-22T12:12:04.9079092Z
2026-10-03 – 2026-10-0332026-10-22T12:12:04.9079092Z
2026-10-02 – 2026-10-0232026-10-22T12:12:04.9079092Z
2026-10-01 – 2026-10-0132026-10-22T12:12:04.9079092Z
2026-09-30 – 2026-09-3052026-10-22T12:12:04.9079092Z
2026-09-29 – 2026-09-2952026-10-22T12:12:04.9079092Z
2026-09-28 – 2026-09-2832026-10-22T12:12:04.9079092Z
2026-09-27 – 2026-09-27132026-10-22T12:12:04.9079092Z
2026-09-26 – 2026-09-26402026-10-22T12:12:04.9079092Z
2026-09-25 – 2026-09-2512026-10-22T12:12:04.9079092Z
2026-09-24 – 2026-09-2452026-10-22T12:12:04.9079092Z
2026-09-23 – 2026-09-2332026-10-22T12:12:04.9079092Z
2026-09-22 – 2026-09-2262026-10-22T12:12:04.9079092Z
2026-09-21 – 2026-09-21172026-10-22T12:12:04.9079092Z
2026-09-18 – 2026-09-1822026-10-22T12:12:04.9079092Z
2026-09-17 – 2026-09-1742026-10-22T12:12:04.9079092Z
2026-09-16 – 2026-09-16202026-10-22T12:12:04.9079092Z
2026-09-15 – 2026-09-15142026-10-22T12:12:04.9079092Z
2026-09-14 – 2026-09-14102026-10-22T12:12:04.9079092Z
2026-09-13 – 2026-09-1372026-10-22T12:12:04.9079092Z
2026-09-12 – 2026-09-1262026-10-22T12:12:04.9079092Z
2026-09-11 – 2026-09-1112026-10-22T12:12:04.9079092Z
2026-09-10 – 2026-09-1022026-10-22T12:12:04.9079092Z
2026-09-09 – 2026-09-0922026-10-22T12:12:04.9079092Z
2026-09-08 – 2026-09-0822026-10-22T12:12:04.9079092Z
2026-09-07 – 2026-09-0722026-10-22T12:12:04.9079092Z
2026-09-05 – 2026-09-0512026-10-22T12:12:04.9079092Z
2026-09-04 – 2026-09-0412026-10-22T12:12:04.9079092Z
2026-09-03 – 2026-09-0312026-10-22T12:12:04.9079092Z
2026-09-01 – 2026-09-0132026-10-22T12:12:04.9079092Z
2026-08-31 – 2026-08-3122026-10-22T12:12:04.9079092Z
2026-08-28 – 2026-08-2872026-10-22T12:12:04.9079092Z
2026-08-27 – 2026-08-2792026-10-22T12:12:04.9079092Z
2026-08-25 – 2026-08-2512026-10-22T12:12:04.9079092Z
2026-08-24 – 2026-08-2472026-10-22T12:12:04.9079092Z
2026-08-23 – 2026-08-2342026-10-22T12:12:04.9079092Z
2026-08-21 – 2026-08-2122026-10-22T12:12:04.9079092Z
2026-08-20 – 2026-08-2032026-10-22T12:12:04.9079092Z
2026-08-19 – 2026-08-1912026-10-22T12:12:04.9079092Z
2026-08-18 – 2026-08-18102026-10-22T12:12:04.9079092Z
2026-08-17 – 2026-08-1722026-10-22T12:12:04.9079092Z
2026-08-15 – 2026-08-1522026-10-22T12:12:04.9079092Z
2026-08-14 – 2026-08-1422026-10-22T12:12:04.9079092Z
2026-08-13 – 2026-08-1312026-10-22T12:12:04.9079092Z
2026-08-09 – 2026-08-09112026-10-22T12:12:04.9079092Z
2026-08-07 – 2026-08-0712026-10-22T12:12:04.9079092Z
2026-08-06 – 2026-08-0612026-10-22T12:12:04.9079092Z
2026-08-04 – 2026-08-0432026-10-22T12:12:04.9079092Z
2026-08-03 – 2026-08-0312026-10-22T12:12:04.9079092Z
2026-08-02 – 2026-08-0232026-10-22T12:12:04.9079092Z
2026-08-01 – 2026-08-0122026-10-22T12:12:04.9079092Z
2026-07-30 – 2026-07-3022026-10-22T12:12:04.9079092Z
2026-07-29 – 2026-07-2912026-10-22T12:12:04.9079092Z
2026-07-28 – 2026-07-2812026-10-22T12:12:04.9079092Z
2026-07-27 – 2026-07-2722026-10-22T12:12:04.9079092Z
2026-07-26 – 2026-07-2612026-10-22T12:12:04.9079092Z
2026-07-25 – 2026-07-2532026-10-22T12:12:04.9079092Z
2026-07-24 – 2026-07-2462026-10-22T12:12:04.9079092Z

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
1.0.017 Oct 20266

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
aggify/aggify

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 21 Oct, 09:03 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:2dbe85291ef22907bcfc6b70332d1e02a426cac9087ec371ebfa8898d33429eb