diff --git a/source/databases-collections.txt b/source/databases-collections.txt index f50ca2cf..f1da923b 100644 --- a/source/databases-collections.txt +++ b/source/databases-collections.txt @@ -70,13 +70,28 @@ Create a Collection Use the ``create_collection()`` method to explicitly create a collection in a MongoDB database. -The following example creates a collection called ``example_collection``: +The following example creates a collection called ``example_collection``. Select the +:guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code: -.. code-block:: python - :emphasize-lines: 2 +.. tabs:: - database = client["test_database"] - database.create_collection("example_collection") + .. tab:: Synchronous + :tabid: sync + + .. code-block:: python + :emphasize-lines: 2 + + database = client["test_database"] + database.create_collection("example_collection") + + .. tab:: Asynchronous + :tabid: async + + .. code-block:: python + :emphasize-lines: 2 + + database = client["test_database"] + await database.create_collection("example_collection") You can specify collection options, such as maximum size and document validation rules, by passing them in as keyword arguments. For a full list of @@ -88,12 +103,26 @@ Time Series Collection Time series collections efficiently store sequences of measurements over a period of time. The following example creates a time series collection called ``example_ts_collection`` -in which the documents' time field is called ``timestamp``: +in which the documents' time field is called ``timestamp``. Select the +:guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code: -.. code-block:: python +.. tabs:: - database = client["test_database"] - database.create_collection("example_ts_collection", timeseries={"timeField": "timestamp"}) + .. tab:: Synchronous + :tabid: sync + + .. code-block:: python + + database = client["test_database"] + database.create_collection("example_ts_collection", timeseries={"timeField": "timestamp"}) + + .. tab:: Asynchronous + :tabid: async + + .. code-block:: python + + database = client["test_database"] + await database.create_collection("example_ts_collection", timeseries={"timeField": "timestamp"}) For more information about using time series data with {+driver-short+}, see the :ref:`pymongo-time-series` guide. @@ -103,12 +132,26 @@ Capped Collection You can create a capped collection that cannot grow beyond a specified memory size or document count. The following example creates a capped collection called -``example_capped_collection`` that has a maximum size of 1000 bytes: +``example_capped_collection`` that has a maximum size of 1000 bytes. Select the +:guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code: -.. code-block:: python +.. tabs:: - database = client["test_database"] - database.create_collection("example_capped_collection", capped=True, size=1000) + .. tab:: Synchronous + :tabid: sync + + .. code-block:: python + + database = client["test_database"] + database.create_collection("example_capped_collection", capped=True, size=1000) + + .. tab:: Asynchronous + :tabid: async + + .. code-block:: python + + database = client["test_database"] + await database.create_collection("example_capped_collection", capped=True, size=1000) To learn more about capped collections, see :manual:`Capped Collections ` in the {+mdb-server+} manual. @@ -122,15 +165,30 @@ you perform on the collection. .. include:: /includes/collation-description.rst The following example creates the same collection as the previous example, -but with a default collation of ``fr_CA``: +but with a default collation of ``fr_CA``. Select the :guilabel:`Synchronous` or +:guilabel:`Asynchronous` tab to see the corresponding code: -.. code-block:: python - :emphasize-lines: 4 +.. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. code-block:: python + + from pymongo.collation import Collation - from pymongo.collation import Collation + database = client["test_database"] + database.create_collection("example_collection", collation=Collation(locale='fr_CA')) - database = client["test_database"] - database.create_collection("example_collection", collation=Collation(locale='fr_CA')) + .. tab:: Asynchronous + :tabid: async + + .. code-block:: python + + from pymongo.collation import Collation + + database = client["test_database"] + await database.create_collection("example_collection", collation=Collation(locale='fr_CA')) Get a List of Collections ------------------------- @@ -140,24 +198,57 @@ You can query for a list of collections in a database by calling the collections in the database and their associated metadata. The following example calls the ``list_collections()`` method and iterates over -the cursor to print the results: +the cursor to print the results. Select the :guilabel:`Synchronous` or +:guilabel:`Asynchronous` tab to see the corresponding code: -.. code-block:: python +.. tabs:: - collection_list = database.list_collections() + .. tab:: Synchronous + :tabid: sync - for c in collection_list: - print(c) + .. code-block:: python + + database = client["test_database"] + collection_list = database.list_collections() + + for c in collection_list: + print(c) + + .. tab:: Asynchronous + :tabid: async + + .. code-block:: python + + database = client["test_database"] + collection_list = await database.list_collections() + + for c in collection_list: + print(c) To query for only the names of the collections in the database, call the ``list_collection_name()`` method as follows: -.. code-block:: python +.. tabs:: + + .. tab:: Synchronous + :tabid: sync - collection_list = database.list_collection_names() + .. code-block:: python - for c in collection_list: - print(c) + collection_list = database.list_collection_names() + + for c in collection_list: + print(c) + + .. tab:: Asynchronous + :tabid: async + + .. code-block:: python + + collection_list = await database.list_collection_names() + + async for c in collection_list: + print(c) For more information about iterating over a cursor, see :ref:`pymongo-cursors`. @@ -167,12 +258,26 @@ Delete a Collection You can delete a collection from the database by using the ``drop_collection()`` method. -The following example deletes the ``test_collection`` collection: +The following example deletes the ``test_collection`` collection. Select the +:guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code: -.. code-block:: python +.. tabs:: + + .. tab:: Synchronous + :tabid: sync - collection = database["test_collection"]; - collection.drop(); + .. code-block:: python + + collection = database["test_collection"] + collection.drop() + + .. tab:: Asynchronous + :tabid: async + + .. code-block:: python + + collection = database["test_collection"] + await collection.drop() .. warning:: Dropping a Collection Deletes All Data in the Collection @@ -283,14 +388,28 @@ By default, the driver uses only those members whose ping times are within 15 mi of the nearest member for queries. To distribute reads between members with higher latencies, pass the ``localThresholdMS`` option to the ``MongoClient()`` constructor. -The following example specifies a local threshold of 35 milliseconds: +The following example specifies a local threshold of 35 milliseconds. Select the +:guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code: -.. code-block:: python - :emphasize-lines: 3 +.. tabs:: - client = MongoClient(replicaSet='repl0', - readPreference=ReadPreference.SECONDARY_PREFERRED, - localThresholdMS=35) + .. tab:: Synchronous + :tabid: sync + + .. code-block:: python + + client = MongoClient(replicaSet='repl0', + readPreference=ReadPreference.SECONDARY_PREFERRED, + localThresholdMS=35) + + .. tab:: Asynchronous + :tabid: async + + .. code-block:: python + + client = AsyncMongoClient(replicaSet='repl0', + readPreference=ReadPreference.SECONDARY_PREFERRED, + localThresholdMS=35) In the preceding example, {+driver-short+} distributes reads between matching members within 35 milliseconds of the closest member's ping time. @@ -310,12 +429,26 @@ if they fail due to a network or server error. You can explicitly disable retryable reads or retryable writes by setting the ``retryReads`` or ``retryWrites`` option to ``False`` in the ``MongoClient()`` constructor. The following -example disables retryable reads and writes for a client: +example disables retryable reads and writes for a client. Select the +:guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code: -.. code-block:: python +.. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. code-block:: python + + client = MongoClient("", + retryReads=False, retryWrites=False) + + .. tab:: Asynchronous + :tabid: async - client = MongoClient("", - retryReads=False, retryWrites=False) + .. code-block:: python + + client = AsyncMongoClient("", + retryReads=False, retryWrites=False) To learn more about supported retryable read operations, see :manual:`Retryable Reads ` in the {+mdb-server+} manual. To learn more about supported retryable write @@ -347,21 +480,44 @@ database. After you define your class, include its name as the generic type for ``Database`` type hint. The following example defines a ``Movie`` class and uses it as the -generic type for a ``Database`` type hint: +generic type for a ``Database`` type hint. Select the :guilabel:`Synchronous` or +:guilabel:`Asynchronous` tab to see the corresponding code: -.. code-block:: python - :emphasize-lines: 5-7, 10 +.. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. code-block:: python + :emphasize-lines: 5-7, 10 + + from typing import TypedDict + from pymongo import MongoClient + from pymongo.database import Database - from typing import TypedDict - from pymongo import MongoClient - from pymongo.database import Database + class Movie(TypedDict): + name: str + year: int - class Movie(TypedDict): - name: str - year: int + client: MongoClient = MongoClient() + database: Database[Movie] = client["test_database"] - client: MongoClient = MongoClient() - database: Database[Movie] = client["test_database"] + .. tab:: Asynchronous + :tabid: async + + .. code-block:: python + :emphasize-lines: 5-7, 10 + + from typing import TypedDict + from pymongo import AsyncMongoClient + from pymongo.asynchronous.database import Database + + class Movie(TypedDict): + name: str + year: int + + client: AsyncMongoClient = AsyncMongoClient() + database: Database[Movie] = client["test_database"] Collection ~~~~~~~~~~ @@ -370,22 +526,46 @@ Adding a generic type to a ``Collection`` type hint is similar to adding a gener to a ``Database`` type hint. First, define a class that inherits from the ``TypedDict`` class and represents the structure of the documents in the collection. Then, include the class name as the generic type for the -``Collection`` type hint, as shown in the following example: - -.. code-block:: python - :emphasize-lines: 5-7,11 +``Collection`` type hint, as shown in the following example. Select the +:guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code: - from typing import TypedDict - from pymongo import MongoClient - from pymongo.collection import Collection +.. tabs:: - class Movie(TypedDict): - name: str - year: int + .. tab:: Synchronous + :tabid: sync + + .. code-block:: python + :emphasize-lines: 5-7,11 + + from typing import TypedDict + from pymongo import MongoClient + from pymongo.asynchronous.collection import Collection + + class Movie(TypedDict): + name: str + year: int + + client: MongoClient = MongoClient() + database = client["test_database"] + collection: Collection[Movie] = database["test_collection"] - client: MongoClient = MongoClient() - database = client["test_database"] - collection: Collection[Movie] = database["test_collection"] + .. tab:: Asynchronous + :tabid: async + + .. code-block:: python + :emphasize-lines: 5-7,11 + + from typing import TypedDict + from pymongo import AsyncMongoClient + from pymongo.collection import Collection + + class Movie(TypedDict): + name: str + year: int + + client: AsyncMongoClient = AsyncMongoClient() + database = client["test_database"] + collection: Collection[Movie] = database["test_collection"] Troubleshooting --------------- diff --git a/source/includes/run-command-async.py b/source/includes/run-command-async.py new file mode 100644 index 00000000..296a1d2c --- /dev/null +++ b/source/includes/run-command-async.py @@ -0,0 +1,23 @@ +# start-hello +database = client.get_database("my_db") + +hello = await database.command("hello") + +print(hello) +# end-hello + +# start-cursor-command +database = client.get_database("sample_mflix") + +result = await database.cursor_command("find", "movies", filter={"runtime": 11}) + +print(result.to_list()) +# end-cursor-command + +# start-runcommand +database = client.get_database("sample_mflix") + +result = await database.command("dbStats") + +print(result) +# end-runcommand \ No newline at end of file diff --git a/source/includes/run-command.py b/source/includes/run-command.py index 132f5116..b923ccd3 100644 --- a/source/includes/run-command.py +++ b/source/includes/run-command.py @@ -1,15 +1,12 @@ # start-hello - database = client.get_database("my_db") hello = database.command("hello") print(hello) - # end-hello # start-readpref - from pymongo.read_preferences import Secondary database = client.get_database("my_db") @@ -17,25 +14,20 @@ hello = database.command("hello", read_preference=Secondary()) print(hello) - # end-readpref # start-cursor-command - database = client.get_database("sample_mflix") result = database.cursor_command("find", "movies", filter={"runtime": 11}) print(result.to_list()) - # end-cursor-command # start-runcommand - database = client.get_database("sample_mflix") result = database.command("dbStats") print(result) - # end-runcommand \ No newline at end of file diff --git a/source/run-command.txt b/source/run-command.txt index 22296294..5617aca1 100644 --- a/source/run-command.txt +++ b/source/run-command.txt @@ -52,74 +52,97 @@ The method will return the result of the command that was run. The following code shows how you can use the ``command()`` method on a ``Database`` to run the ``hello`` -command, which returns information about the server: - -.. io-code-block:: - :copyable: true - - .. input:: /includes/run-command.py - :language: python - :start-after: start-hello - :end-before: end-hello - - .. output:: - :language: json - :visible: false - - { - 'topologyVersion': { - 'processId': ObjectId('6724d211d6b98fa1931e8616'), - 'counter': 6 - }, - 'hosts': ['cluster0-shard-00-00.fxoii.mongodb.net:27017', - 'cluster0-shard-00-01.fxoii.mongodb.net:27017', - 'cluster0-shard-00-02.fxoii.mongodb.net:27017'], - 'setName': 'atlas-13l6uw-shard-0', - 'setVersion': 114, - 'isWritablePrimary': True, - 'secondary': False, - 'primary': 'cluster0-shard-00-02.fxoii.mongodb.net:27017', - 'tags': { - 'workloadType': 'OPERATIONAL', - 'diskState': 'READY', - 'region': 'US_EAST_1', - 'provider': 'AWS', - 'nodeType': 'ELECTABLE', - 'availabilityZone': 'use1-az5' - }, - 'me': 'cluster0-shard-00-02.fxoii.mongodb.net:27017', - 'electionId': ObjectId('7fffffff00000000000000e3'), - 'lastWrite': { - 'opTime': { - 'ts': Timestamp(1730486145, 22), - 't': 227 - }, - 'lastWriteDate': datetime.datetime(2024, 11, 1, 18, 35, 45), - 'majorityOpTime': { - 'ts': Timestamp(1730486145, 22), - 't': 227 - }, - 'majorityWriteDate': datetime.datetime(2024, 11, 1, 18, 35, 45) - }, - 'maxBsonObjectSize': 16777216, - 'maxMessageSizeBytes': 48000000, - 'maxWriteBatchSize': 100000, - 'localTime': datetime.datetime(2024, 11, 1, 18, 35, 45, 309000), - 'logicalSessionTimeoutMinutes': 30, - 'connectionId': 23889, - 'minWireVersion': 0, - 'maxWireVersion': 21, - 'readOnly': False, - 'ok': 1.0, - '$clusterTime': { - 'clusterTime': Timestamp(1730486145, 22), - 'signature': { - 'hash': b"\x1a\xf7{>q%F\xc2\x89\x15\x13W29\x91\xaae'~\xe4", - 'keyId': 7379292132843978793 - } - }, - 'operationTime': Timestamp(1730486145, 22) - } +command, which returns information about the server. Select the :guilabel:`Synchronous` or +:guilabel:`Asynchronous` tab to see the corresponding code: + +.. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. io-code-block:: + :copyable: true + + .. input:: /includes/run-command.py + :language: python + :start-after: start-hello + :end-before: end-hello + + .. output:: + :language: json + :visible: false + + { + 'topologyVersion': { + 'processId': ObjectId('...'), + 'counter': 6 + }, + 'hosts': [...], + 'setName': '...', + 'setVersion': 114, + 'isWritablePrimary': True, + 'secondary': False, + 'primary': '...', + 'tags': {...}, + 'me': '...', + 'electionId': ..., + 'lastWrite': {...}, + 'maxBsonObjectSize': 16777216, + 'maxMessageSizeBytes': 48000000, + 'maxWriteBatchSize': 100000, + 'localTime': ..., + 'logicalSessionTimeoutMinutes': 30, + 'connectionId': ..., + 'minWireVersion': 0, + 'maxWireVersion': 21, + 'readOnly': False, + 'ok': 1.0, + '$clusterTime': {...}, + 'operationTime': ... + } + + .. tab:: Asynchronous + :tabid: async + + .. io-code-block:: + :copyable: true + + .. input:: /includes/run-command-async.py + :language: python + :start-after: start-hello + :end-before: end-hello + + .. output:: + :visible: false + + { + 'topologyVersion': { + 'processId': ObjectId('...'), + 'counter': 6 + }, + 'hosts': [...], + 'setName': '...', + 'setVersion': 114, + 'isWritablePrimary': True, + 'secondary': False, + 'primary': '...', + 'tags': {...}, + 'me': '...', + 'electionId': ..., + 'lastWrite': {...}, + 'maxBsonObjectSize': 16777216, + 'maxMessageSizeBytes': 48000000, + 'maxWriteBatchSize': 100000, + 'localTime': ..., + 'logicalSessionTimeoutMinutes': 30, + 'connectionId': ..., + 'minWireVersion': 0, + 'maxWireVersion': 21, + 'readOnly': False, + 'ok': 1.0, + '$clusterTime': {...}, + 'operationTime': ... + } For a full list of database commands and corresponding parameters, see the :ref:`Additional Information section @@ -137,34 +160,70 @@ The ``CommandCursor`` can be used to iterate over command results. The following example uses the ``cursor_command()`` method on the ``sample_mflix`` database. It runs the ``find`` command on the ``movies`` collection to filter by -documents in which the ``runtime`` field has a value of ``11``. +documents in which the ``runtime`` field has a value of ``11``. Select the +:guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code: -.. io-code-block:: - :copyable: true +.. tabs:: - .. input:: /includes/run-command.py - :language: python - :dedent: - :start-after: start-cursor-command - :end-before: end-cursor-command + .. tab:: Synchronous + :tabid: sync - .. output:: - :language: json - :visible: false + .. io-code-block:: + :copyable: true - { - '_id': ObjectId('573a1390f29313caabcd42e8'), - 'runtime': 11, - 'title': 'The Great Train Robbery', + .. input:: /includes/run-command.py + :language: python + :dedent: + :start-after: start-cursor-command + :end-before: end-cursor-command + + .. output:: + :language: json + :visible: false + + { + '_id': ObjectId(...), + 'runtime': 11, + 'title': 'The Great Train Robbery', + ... + }, + { + {'_id': ObjectId(...), + 'runtime': 11, + 'title': 'Glas', + ... + }, ... - }, - { - {'_id': ObjectId('573a1394f29313caabce0f10'), - 'runtime': 11, - 'title': 'Glas', + + .. tab:: Asynchronous + :tabid: async + + .. io-code-block:: + :copyable: true + + .. input:: /includes/run-command-async.py + :language: python + :dedent: + :start-after: start-cursor-command + :end-before: end-cursor-command + + .. output:: + :language: json + :visible: false + + { + '_id': ObjectId(...), + 'runtime': 11, + 'title': 'The Great Train Robbery', + ... + }, + { + {'_id': ObjectId(...), + 'runtime': 11, + 'title': 'Glas', + ... + }, ... - }, - ... To learn about the response format of the command, see :manual:`Database Commands `. @@ -179,7 +238,7 @@ To learn about the response format of the command, see :manual:`Database Command the command's read preference defaults to ``PRIMARY``. You can set a read preference for command execution by using the ``read_preference`` - parameter, as shown in the following code: + parameter. For example: .. literalinclude:: /includes/run-command.py :language: python @@ -200,24 +259,48 @@ Command Example The following example uses the ``command()`` method to run the ``dbStats`` command to retrieve storage statistics for the -``sample_mflix`` database: +``sample_mflix`` database. Select the :guilabel:`Synchronous` or +:guilabel:`Asynchronous` tab to see the corresponding code: + +.. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. io-code-block:: + :copyable: true + + .. input:: /includes/run-command.py + :language: python + :start-after: start-runcommand + :end-before: end-runcommand + + .. output:: + :visible: false + + {'db': 'sample_mflix', 'collections': 9, 'views': 1, 'objects': 67662, + 'avgObjSize': 1796.788182436227, 'dataSize': 121574282, 'storageSize': 97779712, + 'totalFreeStorageSize': 0, 'numExtents': 0, 'indexes': 13, 'indexSize': 19423232, + 'indexFreeStorageSize': 0, 'fileSize': 0, 'nsSizeMB': 0, 'ok': 1} -.. io-code-block:: - :copyable: true + .. tab:: Asynchronous + :tabid: async - .. input:: /includes/run-command.py - :language: python - :start-after: start-runcommand - :end-before: end-runcommand + .. io-code-block:: + :copyable: true - .. output:: - :language: none - :visible: false + .. input:: /includes/run-command-async.py + :language: python + :start-after: start-runcommand + :end-before: end-runcommand - {'db': 'sample_mflix', 'collections': 9, 'views': 1, 'objects': 67662, - 'avgObjSize': 1796.788182436227, 'dataSize': 121574282, 'storageSize': 97779712, - 'totalFreeStorageSize': 0, 'numExtents': 0, 'indexes': 13, 'indexSize': 19423232, - 'indexFreeStorageSize': 0, 'fileSize': 0, 'nsSizeMB': 0, 'ok': 1} + .. output:: + :visible: false + + {'db': 'sample_mflix', 'collections': 9, 'views': 1, 'objects': 67662, + 'avgObjSize': 1796.788182436227, 'dataSize': 121574282, 'storageSize': 97779712, + 'totalFreeStorageSize': 0, 'numExtents': 0, 'indexes': 13, 'indexSize': 19423232, + 'indexFreeStorageSize': 0, 'fileSize': 0, 'nsSizeMB': 0, 'ok': 1} The output of this command includes information about the collections in the database, and describes the amount and size of data stored across @@ -244,37 +327,82 @@ the class name. The class can be one of the following types: .. include:: /includes/type-hints/typeddict-availability.rst The following example decodes the BSON returned by the ``ping`` command to instances -of the ``RawBSONDocument`` class: +of the ``RawBSONDocument`` class. Select the :guilabel:`Synchronous` or +:guilabel:`Asynchronous` tab to see the corresponding code: + +.. tabs:: + + .. tab:: Synchronous + :tabid: sync + + .. code-block:: python + :emphasize-lines: 3, 6-7 + + from pymongo import MongoClient + from bson.raw_bson import RawBSONDocument + from bson import CodecOptions + + client: MongoClient = MongoClient() + options = CodecOptions(RawBSONDocument) + result = client.admin.command("ping", codec_options=options) -.. code-block:: python - :emphasize-lines: 3, 6-7 + .. tab:: Asynchronous + :tabid: async - from pymongo import MongoClient - from bson.raw_bson import RawBSONDocument - from bson import CodecOptions + .. code-block:: python + :emphasize-lines: 3, 6-7 - client: MongoClient = MongoClient() - options = CodecOptions(RawBSONDocument) - result = client.admin.command("ping", codec_options=options) + from pymongo import AsyncMongoClient + from bson.raw_bson import RawBSONDocument + from bson import CodecOptions + + client: AsyncMongoClient = AsyncMongoClient() + options = CodecOptions(RawBSONDocument) + result = await client.admin.command("ping", codec_options=options) To decode BSON to a subclass of the ``TypedDict`` class, specify the class name in -the ``CodecOptions`` type hint, as shown in the following example: - -.. code-block:: python - :emphasize-lines: 4, 6-8, 11 - - from pymongo import MongoClient - from bson.raw_bson import RawBSONDocument - from bson import CodecOptions - from typing import TypedDict - - class Movie(TypedDict): - name: str - year: int +the ``CodecOptions`` type hint, as shown in the following example. Select the +:guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code: + +.. tabs:: - client: MongoClient = MongoClient() - options: CodecOptions[Movie] = CodecOptions(Movie) - result = client.admin.command("ping", codec_options=options) + .. tab:: Synchronous + :tabid: sync + + .. code-block:: python + :emphasize-lines: 4, 6-8, 11 + + from pymongo import MongoClient + from bson.raw_bson import RawBSONDocument + from bson import CodecOptions + from typing import TypedDict + + class Movie(TypedDict): + name: str + year: int + + client: MongoClient = MongoClient() + options: CodecOptions[Movie] = CodecOptions(Movie) + result = client.admin.command("ping", codec_options=options) + + .. tab:: Asynchronous + :tabid: async + + .. code-block:: python + :emphasize-lines: 4, 6-8, 11 + + from pymongo import AsyncMongoClient + from bson.raw_bson import RawBSONDocument + from bson import CodecOptions + from typing import TypedDict + + class Movie(TypedDict): + name: str + year: int + + client: AsyncMongoClient = AsyncMongoClient() + options: CodecOptions[Movie] = CodecOptions(Movie) + result = await client.admin.command("ping", codec_options=options) Troubleshooting ---------------