Skip to main content

mongo-types PyPI

Type stubs for mongoengine with some basic type stubs for pymongo and bson.

Allows for autocomplete and static typing.

install

pip install mongo-types

Monkey patch mongoengine's QuerySet so we can type it with a generic argument at runtime:

import types
from mongoengine.queryset.queryset import QuerySet

def no_op(self, x):
    return self

QuerySet.__class_getitem__ = types.MethodType(no_op, QuerySet)

usage

After installing and monkey patching, the types should work for the most part, but you'll probably need to change how you write some things.

getting objects to work

By default, the base document is typed to not have an objects property so that each document can type it properly.

Here's a helper class that's useful for simple cases which don't modify the QuerySet.

from typing import Generic, Type, TypeVar
from mongoengine import QuerySet, Document

U = TypeVar("U", bound=Document)

class QuerySetManager(Generic[U]):
    def __get__(self, instance: object, cls: Type[U]) -> QuerySet[U]:
        return QuerySet(cls, cls._get_collection())

class Page(Document):
    meta = {
        "collection": "pages",
    }

    objects = QuerySetManager["Page"]()

    organization = fields.StringField()

replacing usages of queryset_class

before:

from typing import Type
from mongoengine import QuerySet, Document

class PostQuerySet(QuerySet):
    def for_org(self, *, org: str) -> QuerySet:
        return self.filter(organization=org)

    def exists(self) -> bool:
        return self.count() > 0

class Post(Document):
    meta = {
        "collection": "posts",
        "queryset_class": SMSLogQuerySet,
    }

    organization = fields.StringField()
    # --snip--

after:

from typing import Type
from mongoengine import QuerySet, Document

class PostQuerySet(QuerySet["Post"]):
    def for_org(self, *, org: str) -> QuerySet["Post"]:
        return self.filter(organization=org)

    def exists(self) -> bool:
        return self.count() > 0


class QuerySetManager:
    def __get__(self, instance: object, cls: Type[Post]) -> PostQuerySet:
        return PostQuerySet(cls, cls._get_collection())


class Post(Document):
    meta = {
        "collection": "posts",
    }

    objects = QuerySetManager()

    organization = fields.StringField()
    # --snip--

replicating @queryset_manager behavior

before:

from mongoengine import Document, QuerySet, queryset_manager, fields

class UserQuerySet(QuerySet):
    def for_org(self, *, org: str) -> QuerySet:
        return self.filter(organization=org)

class User(Document):
    meta = {
        "collection": "users",
        "queryset_class": UserQuerySet,
    }

    is_active = fields.BooleanField()

    # --snip--

    @queryset_manager
    def objects(self, queryset: QuerySet) -> QuerySet:
        return queryset.filter(is_active=True)

    @queryset_manager
    def all_objects(self, queryset: QuerySet) -> QuerySet:
        return queryset

maybe_user = User.all_objects.first()

after:

from __future__ import annotations
from typing import Type
from mongoengine import QuerySet, Document

class UserQuerySet(QuerySet["User"]):
    def for_org(self, *, org: str) -> UserQuerySet:
        return self.filter(organization=org)


class QuerySetManager:
    def __get__(self, instance: object, cls: Type[User]) -> UserQuerySet:
        return UserQuerySet(cls, cls._get_collection()).filter(is_active=True)


class User(Document):
    meta = {
        "collection": "users",
    }

    is_active = fields.BooleanField()

    # --snip--

    objects = QuerySetManager()

    @classmethod
    def all_objects(cls) -> UserQuerySet:
        return UserQuerySet(cls, cls._get_collection())

maybe_user = User.all_objects().first()

fixing "Model" has no attribute "id"

Mongoengine will define an id field for you automatically. Mongo-types require you specify your id explicitly so that the types can be more strict.

class User(Document):
    meta = {
        "collection": "users",
    }

# becomes

class User(Document):
    meta = {
        "collection": "users",
    }
    id = fields.StringField(db_field="_id", primary_key=True, default=default_id)

# or if you prefer ObjectIds

class User(Document):
    meta = {
        "collection": "users",
    }
    id = fields.ObjectIdField(db_field="_id", primary_key=True, default=ObjectId)

dev

poetry install

# run formatting, linting, and typechecking
s/lint

# build
poetry build -f wheel

# build and publish
poetry publish --build

related

Metadata

Release files for mongo-types 0.15.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mongo-types 0.15.1
File Size Uploaded
mongo-types-0.15.1.tar.gz 23.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mongo-types 0.15.1
File Interpreter ABI Platform
mongo_types-0.15.1-py3-none-any.whl Python 3 none any Details

Total release size: 57.1 kB

Release files / mongo-types-0.15.1.tar.gz

Download URL mongo-types-0.15.1.tar.gz
Size 23.4 kB
Tags Source
SHA-256 checksum
How to use checksums
0a9deeb7733ea7da5db3711d92e22d93556b522f860bbff82e5df44c53bd06a9
BLAKE2b-256 checksum
How to use checksums
9140e79a6caceb8140326963b4ea8829dd8df0434dc815312430b4518bf80c26
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.11 CPython/3.7.3 Darwin/19.4.0

Release files / mongo_types-0.15.1-py3-none-any.whl

Download URL mongo_types-0.15.1-py3-none-any.whl
Size 33.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9417ae5b9a759c09630b5ec7d66904cc333c2d2fcfe75e2760a332ed5e267309
BLAKE2b-256 checksum
How to use checksums
85dbbb06eb4d979ad02820c1ec96975f0d823daa6e93b7a521463c0fd2b9f2b6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.11 CPython/3.7.3 Darwin/19.4.0

Release history Release notifications | RSS feed

This release

0.15.1 This release

2 release files

0.15.0

2 release files

0.14.3

2 release files

0.14.0

2 release files

0.13.1

2 release files

0.11.1

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.4

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.7

2 release files

0.7.6

2 release files

0.7.5

2 release files

0.7.4

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page