### Setup Database for aiohttp Example Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-asyncio.rst Initializes the database by dropping the 'pages' collection and inserting sample documents. This coroutine is intended for demonstration purposes. ```python async def setup_db(db): await db.pages.drop() await db.pages.insert_many([ {"_id": "page-one", "body": "Hello!"}, {"_id": "page-two", "body": "Goodbye."}]) return db ``` -------------------------------- ### Install Motor from Source Source: https://github.com/mongodb/motor/blob/master/doc/installation.rst Install Motor by cloning the git repository and running the pip install command from the root directory. ```bash $ python3 -m pip install . ``` -------------------------------- ### Install and Install Pre-commit Hooks Source: https://github.com/mongodb/motor/blob/master/CONTRIBUTING.md Install the pre-commit package and then install the git hooks to manage linting. This is used for maintaining code style. ```bash pip install pre-commit # or brew install pre-commit for global install. pre-commit install ``` -------------------------------- ### Start MongoDB Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-asyncio.rst Start a MongoDB instance on the default host and port. This is a prerequisite for using Motor. ```bash $ mongod ``` -------------------------------- ### Automatic Client-Side Field Level Encryption Setup Source: https://github.com/mongodb/motor/blob/master/doc/examples/encryption.rst Example demonstrating how to set up automatic client-side field level encryption by creating an AsyncIOMotorClient with AutoEncryptionOpts. This example focuses on creating a new encryption data key. ```python from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorClientEncryption from pymongo.encryption_options import AutoEncryptionOpts async def main(): # Connection string for MongoDB Enterprise or Atlas client_uri = "mongodb://localhost:27017/" # KMS URI for local master key kms_providers = { "local": { "key": b"01234567890123456789012345678901" } } # Explicitly specify the schemaMap to provide local automatic encryption rules schema_map = { "admin.encryptionKOHL.local.documents": { "bsonType": "object", "properties": { "_id": {"bsonType": "objectId"}, "plaintext": {"bsonType": "string"}, "encryptedField": { "encrypt": { "keyId": "606060606060606060606060", "bsonType": "string", "algorithm": "AEAD_AES_256_CBC_SIV_CMAC", } } } } } # Configure the AutoEncryptionOpts auto_encryption_opts = AutoEncryptionOpts( kms_providers=kms_providers, schema_map=schema_map, ) # Create an AsyncIOMotorClient with auto_encryption_opts client = AsyncIOMotorClient(client_uri, auto_encryption_opts=auto_encryption_opts) # Create an AsyncIOMotorClientEncryption instance client_encryption = AsyncIOMotorClientEncryption( client.admin, kms_providers, schema_map=schema_map, ) # Example of creating a data key (replace with actual key generation logic if needed) # key = await client_encryption.create_data_key("local") # print(f"Created data key: {key}") # Close the client client.close() if __name__ == "__main__": import asyncio asyncio.run(main()) ``` -------------------------------- ### Install Motor with All Dependencies Source: https://github.com/mongodb/motor/blob/master/README.md Install Motor with all common optional dependencies for comprehensive feature support. ```bash pip install "motor[gssapi,aws,ocsp,snappy,srv,zstd,encryption]" ``` -------------------------------- ### Install Motor with Snappy Compression Source: https://github.com/mongodb/motor/blob/master/README.md Install Motor with the 'snappy' extra dependency for wire protocol compression using snappy. ```bash pip install "motor[snappy]" ``` -------------------------------- ### Install Motor Source: https://github.com/mongodb/motor/blob/master/README.md Install the base Motor library using pip. ```bash pip install motor ``` -------------------------------- ### Install Motor with OCSP Support Source: https://github.com/mongodb/motor/blob/master/README.md Install Motor with the 'ocsp' extra dependency for OCSP support. ```bash pip install "motor[ocsp]" ``` -------------------------------- ### Start aiohttp Web Server with Motor Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-asyncio.rst Initializes the database connection and starts the aiohttp web server. It configures routes and passes the database handle to the application. ```python async def main(): client = AsyncIOMotorClient() db = client.test await setup_db(db) app = web.Application() app["db"] = db app.router.add_get("/pages/{page_name}", handle_request) runner = web.AppRunner(app) await runner.setup() site = web.TCPSite(runner, 'localhost', 8080) await site.start() if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Tornado Application Startup with Motor Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-tornado.rst Example of initializing a Motor client and accessing a database during Tornado application startup. ```python db = motor.motor_tornado.MotorClient().test_database application = tornado.web.Application([ (r'/', MainHandler) ], db=db) ``` -------------------------------- ### Server-Side Field Level Encryption Enforcement Setup Source: https://github.com/mongodb/motor/blob/master/doc/examples/encryption.rst Example demonstrating how to set up automatic client-side field level encryption with server-side schema validation to enforce encryption of specific fields. This setup uses AsyncIOMotorClientEncryption to create a data key and a collection with encryption rules. ```python from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorClientEncryption from pymongo.encryption_options import AutoEncryptionOpts async def main(): # Connection string for MongoDB Enterprise or Atlas client_uri = "mongodb://localhost:27017/" # KMS URI for local master key kms_providers = { "local": { "key": b"01234567890123456789012345678901" } } # Explicitly specify the schemaMap to provide local automatic encryption rules schema_map = { "admin.encryptionKOHL.local.documents": { "bsonType": "object", "properties": { "_id": {"bsonType": "objectId"}, "plaintext": {"bsonType": "string"}, "encryptedField": { "encrypt": { "keyId": "606060606060606060606060", "bsonType": "string", "algorithm": "AEAD_AES_256_CBC_SIV_CMAC", } } } } } # Configure the AutoEncryptionOpts auto_encryption_opts = AutoEncryptionOpts( kms_providers=kms_providers, schema_map=schema_map, ) # Create an AsyncIOMotorClient with auto_encryption_opts client = AsyncIOMotorClient(client_uri, auto_encryption_opts=auto_encryption_opts) # Create an AsyncIOMotorClientEncryption instance client_encryption = AsyncIOMotorClientEncryption( client.admin, kms_providers, schema_map=schema_map, ) # Example of creating a data key (replace with actual key generation logic if needed) # key = await client_encryption.create_data_key("local") # print(f"Created data key: {key}") # Create a collection with schema validation for encryption # await client.get_database("db").command( # "create", "collection", # validator={ # "$jsonSchema": { # "bsonType": "object", # "properties": { # "encryptedField": { # "encrypt": { # "keyId": key, # "bsonType": "string", # "algorithm": "AEAD_AES_256_CBC_SIV_CMAC", # } # } # } # } # }, # validationLevel="strict", # validationAction="error", # ) # Close the client client.close() if __name__ == "__main__": import asyncio asyncio.run(main()) ``` -------------------------------- ### Install Motor with GSSAPI Authentication Source: https://github.com/mongodb/motor/blob/master/README.md Install Motor with the 'gssapi' extra dependency for GSSAPI authentication support. ```bash pip install "motor[gssapi]" ``` -------------------------------- ### Install Motor with Zstandard Compression Source: https://github.com/mongodb/motor/blob/master/README.md Install Motor with the 'zstd' extra dependency for wire protocol compression using zstandard. ```bash pip install "motor[zstd]" ``` -------------------------------- ### MotorClient Command Monitoring Example Source: https://github.com/mongodb/motor/blob/master/doc/examples/monitoring.rst Demonstrates command monitoring with MotorClient. This example shows how to initialize MotorClient and register a command listener to observe database operations. ```python from tornado.ioloop import IOLoop from motor.motor_tornado import MotorClient from pymongo import monitoring class MyCommandLogger(monitoring.CommandListener): def started(self, event): print( f"Command {event.command_name} with request id {event.request_id} started on server {event.connection_id}" ) def succeeded(self, event): print(f"Command {event.command_name} with request id {event.request_id} on server {event.connection_id}" f" succeeded in {event.duration_micros} microseconds") def failed(self, event): print(f"Command {event.command_name} with request id {event.request_id} on server {event.connection_id}" f" failed in {event.duration_micros} microseconds") loop = IOLoop.current() client = MotorClient(event_loop=loop) client.event_listeners.append(MyCommandLogger()) async def run_command(): db = client.testdb await db.testcollection.insert_one({"name": "test"}) loop.run_sync(run_command) ``` -------------------------------- ### Motor 2.0: Async Client Session Start Source: https://github.com/mongodb/motor/blob/master/doc/migrate-to-motor-2.rst Shows the updated way to start a client session in Motor 2.0, which now requires 'await' as 'start_session' is a coroutine. ```python3 session = client.start_session() doc = await client.db.collection.find_one({}, session=session) session.end_session() ``` ```python3 with client.start_session() as session: doc = client.db.collection.find_one({}, session=session) ``` ```python3 session = await client.start_session() doc = await client.db.collection.find_one({}, session=session) await session.end_session() ``` ```python3 async with client.start_session() as session: doc = await client.db.collection.find_one({}, session=session) ``` -------------------------------- ### Tornado Application Setup with Motor Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-tornado.rst Demonstrates setting up a Tornado application and configuring Motor's database client. It highlights the importance of creating the MotorClient after forking processes for multi-CPU deployments. ```python import tornado.web import tornado.httpserver from tornado.ioloop import IOLoop from motor.motor_tornado import MotorClient class MainHandler(tornado.web.RequestHandler): def get(self): db = self.settings['db'] # Create the application before creating a MotorClient. application = tornado.web.Application([ (r'/', MainHandler) ]) server = tornado.httpserver.HTTPServer(application) server.bind(8888) # Forks one process per CPU. server.start(0) # Now, in each child process, create a MotorClient. application.settings['db'] = MotorClient().test_database IOLoop.current().start() ``` -------------------------------- ### Install Motor with Network Compression Dependencies Source: https://github.com/mongodb/motor/blob/master/doc/configuration.rst Install Motor with optional dependencies for Snappy and Zstandard compression. This enables network traffic compression between the client and MongoDB server. ```bash $ python3 -m pip install "motor[snappy, zstd]" ``` -------------------------------- ### Install Motor with SRV Support Source: https://github.com/mongodb/motor/blob/master/README.md Install Motor with the 'srv' extra dependency to support mongodb+srv:// URIs. ```bash pip install "motor[srv]" ``` -------------------------------- ### Install Motor with Pip Source: https://github.com/mongodb/motor/blob/master/doc/installation.rst Install the Motor library from PyPI using pip. This command automatically handles prerequisite packages. ```bash $ python3 -m pip install motor ``` -------------------------------- ### Change Notification Example Output Source: https://github.com/mongodb/motor/blob/master/doc/examples/tornado_change_stream_example.rst Example of the JSON output received for insert, update, and delete operations on the 'test' collection. ```text Changes {'documentKey': {'_id': ObjectId('5a2a6967ea2dcf7b1c721cfb')}, 'fullDocument': {'_id': ObjectId('5a2a6967ea2dcf7b1c721cfb')}, 'ns': {'coll': 'test', 'db': 'test'}, 'operationType': 'insert'} {'documentKey': {'_id': ObjectId('5a2a6967ea2dcf7b1c721cfb')}, 'ns': {'coll': 'test', 'db': 'test'}, 'operationType': 'update', 'updateDescription': {'removedFields': [], 'updatedFields': {'x': 1.0}}} {'documentKey': {'_id': ObjectId('5a2a6967ea2dcf7b1c721cfb')}, 'ns': {'coll': 'test', 'db': 'test'}, 'operationType': 'delete'} ``` -------------------------------- ### Install Motor with AWS Authentication Source: https://github.com/mongodb/motor/blob/master/README.md Install Motor with the 'aws' extra dependency for MONGODB-AWS authentication. ```bash pip install "motor[aws]" ``` -------------------------------- ### Get Motor Version Source: https://github.com/mongodb/motor/blob/master/README.md Execute this command to find the exact version of Motor installed, including its patch level. ```bash python -c "import motor; print(motor.version)" ``` -------------------------------- ### Install Motor with Client-Side Field Level Encryption Source: https://github.com/mongodb/motor/blob/master/README.md Install Motor with the 'encryption' extra dependency for Client-Side Field Level Encryption. ```bash pip install "motor[encryption]" ``` -------------------------------- ### Import Motor Tornado Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-tornado.rst Ensures the Motor Tornado driver is installed and accessible. ```python import motor.motor_tornado ``` -------------------------------- ### Bulk Write with Write Concern and Timeout Source: https://github.com/mongodb/motor/blob/master/doc/examples/bulk.rst This example shows how to configure a specific write concern and timeout for a bulk write operation. It demonstrates handling `BulkWriteError` when a write concern timeout occurs. ```python >>> from pymongo import WriteConcern >>> async def f(): ... coll = db.get_collection("test", write_concern=WriteConcern(w=4, wtimeout=1)) ... try: ... await coll.bulk_write([InsertOne({"a": i}) for i in range(4)]) ... except BulkWriteError as bwe: ... pprint(bwe.details) ... >>> IOLoop.current().run_sync(f) ``` -------------------------------- ### Accessing a Database Source: https://github.com/mongodb/motor/blob/master/doc/api-asyncio/asyncio_motor_client.rst Demonstrates how to get an AsyncIOMotorDatabase instance from an AsyncIOMotorClient using dictionary-style or attribute-style access. ```APIDOC ## Accessing a Database ### Description Get the `db_name` :class:`AsyncIOMotorDatabase` on :class:`AsyncIOMotorClient` `client`. Raises :class:`~pymongo.errors.InvalidName` if an invalid database name is used. ### Method Attribute access or dictionary-style access ### Endpoint client.db_name or client[db_name] ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python # Using attribute access db = client.mydatabase # Using dictionary-style access db = client["mydatabase"] ``` ### Response #### Success Response (200) An instance of `AsyncIOMotorDatabase`. #### Response Example ```python # Example of a database object (representation may vary) ``` ``` -------------------------------- ### Install Motor with Encryption Support Source: https://github.com/mongodb/motor/blob/master/doc/examples/encryption.rst Install Motor with the necessary dependencies for encryption support. Ensure pip is version 19 or later for Linux manylinux2010 wheel support. ```bash $ python -m pip install 'motor[encryption]' ``` -------------------------------- ### Get Tornado Version Source: https://github.com/mongodb/motor/blob/master/README.md If you are using Tornado, run this command to obtain its exact version. ```bash python -c "import tornado; print(tornado.version)" ``` -------------------------------- ### Configure CaresResolver Source: https://github.com/mongodb/motor/blob/master/doc/changelog.rst Enable non-blocking DNS lookups using the c-ares resolver by installing pycares and configuring CaresResolver. ```python Resolver.configure('tornado.platform.caresresolver.CaresResolver') ``` -------------------------------- ### Finding a Single Document Matching Criteria Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-tornado.rst Demonstrates how to retrieve the first document that matches a specified query using `find_one`. The example finds a document where the field 'i' is less than 1. ```python async def do_find_one(): document = await db.test_collection.find_one({"i": {"$lt": 1}}) pprint.pprint(document) IOLoop.current().run_sync(do_find_one) ``` -------------------------------- ### Implement Command Listener in Python Source: https://github.com/mongodb/motor/blob/master/doc/examples/monitoring.rst Subclass pymongo.monitoring.CommandListener to receive notifications for command start, success, and failure events. Ensure callbacks are thread-safe. ```python from pymongo import monitoring class MyCommandLogger(monitoring.CommandListener): def started(self, event): print( f"Command {event.command_name} with request id {event.request_id} started on server {event.connection_id}" ) def succeeded(self, event): print(f"Command {event.command_name} with request id {event.request_id} on server {event.connection_id}" f" succeeded in {event.duration_micros} microseconds") def failed(self, event): print(f"Command {event.command_name} with request id {event.request_id} on server {event.connection_id}" f" failed in {event.duration_micros} microseconds") ``` -------------------------------- ### Migrate from WaitOp to Futures Source: https://github.com/mongodb/motor/blob/master/doc/changelog.rst Replace Motor.WaitOp with Futures for handling asynchronous operations. This example shows how to convert a Tornado 2/Motor 0.1 style callback to the new Future-based API. ```python @gen.engine def get_some_documents(): cursor = collection.find().sort('_id').limit(2) cursor.to_list(callback=(yield gen.Callback('key'))) do_something_while_we_wait() try: documents = yield motor.WaitOp('key') print documents except Exception, e: print e ``` ```python @gen.coroutine def f(): cursor = collection.find().sort('_id').limit(2) future = cursor.to_list(2) do_something_while_we_wait() try: documents = yield future print documents except Exception, e: print e ``` -------------------------------- ### Tail Oplog Example with Tailable Cursor Source: https://github.com/mongodb/motor/blob/master/doc/examples/tailable-cursors.rst Use CursorType.TAILABLE_AWAIT and oplog_replay=True to tail the oplog. The oplog_replay option is ignored in MongoDB 4.4+ as oplog queries are automatically optimized. The cursor remains alive as long as new documents are added. ```python from asyncio import sleep from pymongo.cursor import CursorType async def tail_oplog_example(): oplog = client.local.oplog.rs first = await oplog.find().sort("$natural", pymongo.ASCENDING).limit(-1).next() print(first) ts = first["ts"] while True: # For a regular capped collection CursorType.TAILABLE_AWAIT is the # only option required to create a tailable cursor. When querying the # oplog, the oplog_replay option enables an optimization to quickly # find the 'ts' value we're looking for. The oplog_replay option # can only be used when querying the oplog. Starting in MongoDB 4.4 # this option is ignored by the server as queries against the oplog # are optimized automatically by the MongoDB query engine. cursor = oplog.find( {"ts": {"$gt": ts}}, cursor_type=CursorType.TAILABLE_AWAIT, oplog_replay=True, ) while cursor.alive: async for doc in cursor: ts = doc["ts"] print(doc) # We end up here if the find() returned no documents or if the # tailable cursor timed out (no new documents were added to the # collection for more than 1 second). await sleep(1) ``` -------------------------------- ### Retrieve server info using hello command in Motor 3 Source: https://github.com/mongodb/motor/blob/master/doc/migrate-to-motor-3.rst Replace direct access to max_bson_size, max_message_size, and max_write_batch_size with a call to the hello command. ```python doc = await client.admin.command('hello') max_bson_size = doc['maxBsonObjectSize'] max_message_size = doc['maxMessageSizeBytes'] max_write_batch_size = doc['maxWriteBatchSize'] ``` -------------------------------- ### Basic AsyncIOMotorClient Usage with Type Hints Source: https://github.com/mongodb/motor/blob/master/doc/examples/type_hints.rst Demonstrates basic usage of AsyncIOMotorClient with default, unspecified document types. Ensure your IDE is configured for type hints. ```python from motor.motor_asyncio import AsyncIOMotorClient async def main(): client: AsyncIOMotorClient = AsyncIOMotorClient() collection = client.test.test inserted = await collection.insert_one({"x": 1, "tags": ["dog", "cat"]}) retrieved = await collection.find_one({"x": 1}) assert isinstance(retrieved, dict) ``` -------------------------------- ### Create Motor Client (Default) Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-tornado.rst Instantiate a Motor client connecting to MongoDB on the default host and port. ```python client = motor.motor_tornado.MotorClient() ``` -------------------------------- ### Serve Compressed Static Content from GridFS with AIOHTTP Source: https://github.com/mongodb/motor/blob/master/doc/examples/aiohttp_gridfs_example.rst This snippet shows how to set up an aiohttp web server to serve files from GridFS. It requires the aiohttp framework and Motor. Ensure MongoDB is running and files are uploaded to GridFS. ```python import aiohttp.web import motor.aiohttp async def serve_file(request): filename = request.match_info.get('filename', 'my_file') try: # Assuming you have a Motor client and database initialized # For example: client = motor.aiohttp.MotorClient() # db = client.test_database # fs = motor.aiohttp.AIOHTTPGridFS(db, 'fs') # This is a placeholder for actual GridFS interaction # In a real app, you'd fetch the file from GridFS # file_obj = await fs.get_last_version(filename) # if file_obj: # return aiohttp.web.Response(body=file_obj.read(), content_type=file_obj.content_type) # else: # return aiohttp.web.Response(status=404, text='File not found') # Placeholder response for demonstration return aiohttp.web.Response(text=f'Serving file: {filename}') except Exception as e: return aiohttp.web.Response(status=500, text=str(e)) async def create_app(): app = aiohttp.web.Application() # Placeholder for GridFS setup # client = motor.aiohttp.MotorClient() # db = client.test_database # fs = motor.aiohttp.AIOHTTPGridFS(db, 'fs') app.router.add_get('/fs/{filename}', serve_file) return app async def main(): app = await create_app() runner = aiohttp.web.AppRunner(app) await runner.setup() site = aiohttp.web.TCPSite(runner, 'localhost', 8080) await site.start() print('Server started on http://localhost:8080') # Keep the server running await aiohttp.web.run_app(app) if __name__ == '__main__': # This part is typically handled by a runner in a real application # For simplicity, we'll use asyncio.run import asyncio asyncio.run(main()) ``` -------------------------------- ### Create Motor Client (Host and Port) Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-tornado.rst Instantiate a Motor client specifying the MongoDB host and port. ```python client = motor.motor_tornado.MotorClient("localhost", 27017) ``` -------------------------------- ### Create Motor Client (Replica Set) Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-tornado.rst Instantiate a Motor client for a MongoDB replica set using a connection URI. ```python client = motor.motor_tornado.MotorClient('mongodb://host1,host2/?replicaSet=my-replicaset-name') ``` -------------------------------- ### Get Database Reference Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-tornado.rst Obtain a reference to a specific database from the Motor client. This operation is non-blocking and does not perform I/O. ```python db = client.test_database ``` ```python db = client["test_database"] ``` -------------------------------- ### Sequentially Inserting Multiple Documents Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-tornado.rst Illustrates the correct way to insert multiple documents sequentially using `await` with `insert_one` inside a loop to avoid performance issues associated with concurrent operations. ```python async def do_insert(): for i in range(2000): await db.test_collection.insert_one({"i": i}) IOLoop.current().run_sync(do_insert) ``` -------------------------------- ### Get Python Version Source: https://github.com/mongodb/motor/blob/master/README.md Use this command to retrieve the exact Python version, including the patch level, for debugging purposes. ```bash python -c "import sys; print(sys.version)" ``` -------------------------------- ### Connect to Replica Set with MotorClient Source: https://github.com/mongodb/motor/blob/master/doc/changelog.rst Connect to a replica set using the 'replicaSet' URI option or parameter with MotorClient. This is the recommended approach since Motor 1.0. ```python MotorClient("mongodb://hostname/?replicaSet=my-rs") ``` ```python MotorClient(host, port, replicaSet="my-rs") ``` -------------------------------- ### Typed Database Schema Source: https://github.com/mongodb/motor/blob/master/doc/examples/type_hints.rst Example of defining a TypedDict to model documents for an entire database. This sets a schema for all documents within the specified database. ```python from typing import TypedDict from motor.motor_asyncio import AsyncIOMotorClient from motor.motor_asyncio import AsyncIOMotorDatabase class Movie(TypedDict): name: str year: int # Example usage (not a full runnable snippet): # async def setup_typed_database(): # client: AsyncIOMotorClient = AsyncIOMotorClient() # db: AsyncIOMotorDatabase[Movie] = client.my_typed_db ``` -------------------------------- ### Create Motor Client (Connection URI) Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-tornado.rst Instantiate a Motor client using a MongoDB connection URI. ```python client = motor.motor_tornado.MotorClient("mongodb://localhost:27017") ``` -------------------------------- ### Accessing Databases Source: https://github.com/mongodb/motor/blob/master/doc/api-tornado/motor_client.rst Demonstrates how to access a specific database using dictionary-style or attribute-style access on the MotorClient instance. ```APIDOC ## Accessing Databases ### Description Get a `MotorDatabase` on `MotorClient` `client` using either dictionary-style access `client[db_name]` or attribute-style access `client.db_name`. Raises `pymongo.errors.InvalidName` if an invalid database name is used. ### Method Attribute Access or Dictionary Access ### Endpoint N/A (SDK Method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python # Using dictionary-style access db = client["my_database"] # Using attribute-style access db = client.my_database ``` ### Response #### Success Response (200) Returns a `MotorDatabase` object representing the specified database. #### Response Example ```json { "database_name": "my_database" } ``` ``` -------------------------------- ### Get PyMongo Version and C Extension Status Source: https://github.com/mongodb/motor/blob/master/README.md This command retrieves the exact PyMongo version and indicates whether the C extension is enabled. ```bash python -c "import pymongo; print(pymongo.version); print(pymongo.has_c())" ``` -------------------------------- ### Count Documents in MongoDB Collection Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-asyncio.rst Use `count_documents` to get the total number of documents or those matching a query. Requires an active asyncio event loop. ```python async def do_count(): n = await db.test_collection.count_documents({}) print("%s documents in collection" % n) n = await db.test_collection.count_documents({"i": {"$gt": 1000}}) print("%s documents where i > 1000" % n) loop = client.get_io_loop() loop.run_until_complete(do_count()) ``` -------------------------------- ### Create AsyncIOMotorClient Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-asyncio.rst Create an instance of AsyncIOMotorClient to connect to MongoDB. This establishes the connection to your deployment. ```python import motor.motor_asyncio client = motor.motor_asyncio.AsyncIOMotorClient() ``` ```python client = motor.motor_asyncio.AsyncIOMotorClient("localhost", 27017) ``` ```python client = motor.motor_asyncio.AsyncIOMotorClient("mongodb://localhost:27017") ``` ```python client = motor.motor_asyncio.AsyncIOMotorClient('mongodb://host1,host2/?replicaSet=my-replicaset-name') ``` -------------------------------- ### Accessing a MongoDB Collection in Motor Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-tornado.rst Shows how to get a reference to a MongoDB collection using dot notation or dictionary-style access. This operation is non-blocking and does not require 'await'. ```python collection = db.test_collection ``` ```python collection = db["test_collection"] ``` -------------------------------- ### Accessing Collections Source: https://github.com/mongodb/motor/blob/master/doc/api-asyncio/asyncio_motor_database.rst You can access collections within a database using dictionary-style access or attribute-style access. This allows you to get an AsyncIOMotorCollection object for a specific collection name. ```APIDOC ## Accessing Collections ### Description Get the `AsyncIOMotorCollection` of `AsyncIOMotorDatabase` `db`. ### Method - Dictionary-style access: `db[collection_name]` - Attribute-style access: `db.collection_name` ### Parameters #### Path Parameters - **collection_name** (string) - Required - The name of the collection to access. ### Raises - :class:`~pymongo.errors.InvalidName`: If an invalid collection name is used. ``` -------------------------------- ### Run a MongoDB Command with Motor Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-tornado.rst Shows how to execute a raw MongoDB command using `db.command`. It is recommended to use `bson.SON` for command parameters to maintain order. ```python from bson import SON async def use_distinct_command(): response = await db.command(SON([("distinct", "test_collection"), ("key", "i")])) IOLoop.current().run_sync(use_distinct_command) ``` -------------------------------- ### Motor 0.5 aggregate with older MongoDB versions Source: https://github.com/mongodb/motor/blob/master/doc/changelog.rst Illustrates how to use MotorCollection.aggregate with MongoDB versions 2.4 and older by setting cursor=False to get all results in one document. ```python # Motor 0.5 with MongoDB 2.4 and older. reply = yield collection.aggregate(cursor=False) for doc in reply['results']: print(doc) ``` -------------------------------- ### Add Motor 2.5 to requirements.txt Source: https://github.com/mongodb/motor/blob/master/doc/migrate-to-motor-3.rst To begin the migration to Motor 3.0, ensure your project uses at least Motor version 2.5. Add this line to your requirements.txt file. ```text motor >= 2.5, < 3.0 ``` -------------------------------- ### AsyncIOMotorClient with Specific Document Type Hint Source: https://github.com/mongodb/motor/blob/master/doc/examples/type_hints.rst Shows how to specify a more accurate type hint for the document type, using Dict[str, Any]. This requires importing Any and Dict from typing. ```python from typing import Any, Dict from motor.motor_asyncio import AsyncIOMotorClient async def main(): client: AsyncIOMotorClient[Dict[str, Any]] = AsyncIOMotorClient() collection = client.test.test inserted = await collection.insert_one({"x": 1, "tags": ["dog", "cat"]}) retrieved = await collection.find_one({"x": 1}) assert isinstance(retrieved, dict) ``` -------------------------------- ### Configure ThreadedResolver Source: https://github.com/mongodb/motor/blob/master/doc/changelog.rst Enable non-blocking DNS lookups by configuring Tornado's ThreadedResolver. ```python Resolver.configure('tornado.netutil.ThreadedResolver') ``` -------------------------------- ### Tornado Change Stream Application Source: https://github.com/mongodb/motor/blob/master/doc/examples/tornado_change_stream_example.rst This Python script uses Motor with Tornado to watch for MongoDB collection changes and stream them to a web page via WebSockets. Ensure Motor is installed and a MongoDB server is running. ```python3 import asyncio import json from tornado.escape import json_encode from tornado.ioloop import IOLoop from tornado.web import Application, RequestHandler, asynchronous from tornado.websocket import WebSocketHandler from motor.motor_tornado import MotorClient class IndexHandler(RequestHandler): def get(self): self.render('index.html') class ChangeStreamWebSocketHandler(WebSocketHandler): clients = set() def open(self): ChangeStreamWebSocketHandler.clients.add(self) print('WebSocket opened') def on_close(self): ChangeStreamWebSocketHandler.clients.remove(self) print('WebSocket closed') def on_message(self, message): # This handler does not expect messages from the client pass @classmethod async def send_message(cls, message): encoded_message = json_encode(message) for client in cls.clients: try: client.write_message(encoded_message) except Exception as e: print(f'Error sending message: {e}') cls.clients.remove(client) async def watch_collection(db): collection = db.test async with collection.watch() as stream: async for change in stream: print(f'Received change: {change}') await ChangeStreamWebSocketHandler.send_message(change) def make_app(): return Application([ (r"/", IndexHandler), (r"/websocket", ChangeStreamWebSocketHandler), ]) async def main(): # Connect to MongoDB client = MotorClient('mongodb://localhost:27017') db = client.test # Start the change stream watcher in the background asyncio.create_task(watch_collection(db)) # Start the Tornado web server app = make_app() app.listen(8888) print('Listening on http://localhost:8888') await asyncio.Event().wait() # Keep the server running if __name__ == "__main__": # Create a dummy index.html file for the example with open('index.html', 'w') as f: f.write(''' Tornado Change Stream

MongoDB Change Stream

Changes:


    
''') IOLoop.current().run_sync(main) ``` -------------------------------- ### Run Linters Manually with Tox Source: https://github.com/mongodb/motor/blob/master/CONTRIBUTING.md Execute the 'lint' module using tox to manually run pre-commit checks on the codebase. ```bash tox -m lint ``` -------------------------------- ### Migrate from Callback API to Futures Source: https://github.com/mongodb/motor/blob/master/doc/migrate-to-motor-2.rst Demonstrates how to adapt code that uses the old callback-based API to the Futures API by adding a callback to a Future object. ```python3 def callback(result, error): if error: print(error) else: print(result) collection.find_one({}, callback=callback) ``` ```python3 def callback(future): try: result = future.result() print(result) except Exception as exc: print(exc) future = collection.find_one({}) future.add_done_callback(callback) ``` ```python3 collection.find_one({}).add_done_callback(callback) ``` -------------------------------- ### Custom File Digest with GridFS in Motor Source: https://github.com/mongodb/motor/blob/master/doc/migrate-to-motor-3.rst Implement custom file digests like SHA256 outside of GridFS and store them with file metadata. This example demonstrates how to compute and attach a SHA256 hash to a file uploaded via GridFS. ```python import hashlib from motor.motor_tornado import MotorClient from gridfs import GridFSBucket my_db = MotorClient().test fs = GridFSBucket(my_db) grid_in = fs.open_upload_stream("test_file") file_data = b'...' # Replace with actual file data sha356 = hashlib.sha256(file_data).hexdigest() await grid_in.write(file_data) grid_in.sha356 = sha356 # Set the custom 'sha356' field await grid_in.close() ``` -------------------------------- ### Replace cursor indexing/slicing with skip and limit Source: https://github.com/mongodb/motor/blob/master/doc/changelog.rst Demonstrates the recommended way to access specific documents from a cursor by using .skip(i).limit(-1) instead of direct indexing or slicing, which is no longer supported. ```python cursor = collection.find().skip(i).limit(-1) yield cursor.fetch_next doc = cursor.next_object() ``` -------------------------------- ### Test MongoDB Connection with run_sync Source: https://github.com/mongodb/motor/blob/master/doc/changelog.rst Use IOLoop.run_sync to test MongoDB availability before application startup. This replaces the removed open_sync method. ```python loop = tornado.ioloop.IOLoop.current() client = motor.motor_tornado.MotorClient(host, port) try: loop.run_sync(client.open) except pymongo.errors.ConnectionFailure: print "Can't connect" ``` -------------------------------- ### Use Python 3.5 native coroutines with async/await Source: https://github.com/mongodb/motor/blob/master/doc/changelog.rst Demonstrates how to use Python 3.5 native coroutines with the async and await keywords for asynchronous operations. ```python async def f(): await collection.insert({'_id': 1}) ``` -------------------------------- ### Connect to MongoDB with Authentication Source: https://github.com/mongodb/motor/blob/master/doc/examples/authentication.rst Use a MongoDB connection URI to create an authenticated client. Motor logs in on demand when an operation is first attempted. ```python uri = "mongodb://user:pass@localhost:27017/database_name" client = motor.motor_tornado.MotorClient(uri) ``` -------------------------------- ### Replacing MotorDatabase.profiling_info Source: https://github.com/mongodb/motor/blob/master/doc/migrate-to-motor-3.rst The 'profiling_info' method is removed. Query the 'system.profile' collection directly using find() to retrieve profiling data. This is an awaitable operation. ```python profiling_info = db.profiling_info() ``` ```python profiling_info = await db['system.profile'].find().to_list() ``` -------------------------------- ### Migrate fsync command to Motor 3 Source: https://github.com/mongodb/motor/blob/master/doc/migrate-to-motor-3.rst Use motor.motor_tornado.MotorDatabase.command to run the fsync command directly. ```python await client.admin.command('fsync', lock=True) ``` -------------------------------- ### Accessing Collections Source: https://github.com/mongodb/motor/blob/master/doc/api-tornado/motor_database.rst Demonstrates how to access a MongoDB collection using either dictionary-style or attribute-style access. ```APIDOC ## Accessing Collections ### Description Get the `collection_name` :class:`MotorCollection` of :class:`MotorDatabase` `db`. Raises :class:`~pymongo.errors.InvalidName` if an invalid collection name is used. ### Method `db[collection_name]` or `db.collection_name` ``` -------------------------------- ### Find Documents with Motor using async for Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-asyncio.rst Iterate over documents matching a query one at a time using an 'async for' loop with a cursor. This is an efficient way to handle results. ```python async def do_find(): c = db.test_collection async for document in c.find({"i": {"$lt": 2}}): pprint.pprint(document) loop = client.get_io_loop() loop.run_until_complete(do_find()) ``` -------------------------------- ### Inserting Multiple Documents in a Batch Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-tornado.rst Shows how to efficiently insert a large number of documents by using `insert_many` to perform the operation in a single batch, improving performance. ```python async def do_insert(): result = await db.test_collection.insert_many([{"i": i} for i in range(2000)]) print("inserted %d docs" % (len(result.inserted_ids),)) IOLoop.current().run_sync(do_insert) ``` -------------------------------- ### Bulk Write with TypedDict Source: https://github.com/mongodb/motor/blob/master/doc/examples/type_hints.rst Shows how to perform a bulk write operation using InsertOne with a TypedDict. Similar to insert_one, accessing the auto-generated '_id' may cause type-checking issues. ```python from typing import TypedDict from motor.motor_asyncio import AsyncIOMotorClient from motor.motor_asyncio import AsyncIOMotorCollection from pymongo.operations import InsertOne class Movie(TypedDict): name: str year: int async def main(): client: AsyncIOMotorClient = AsyncIOMotorClient() collection: AsyncIOMotorCollection[Movie] = client.test.test inserted = await collection.bulk_write( [InsertOne(Movie(name="Jurassic Park", year=1993))] ) result = await collection.find_one({"name": "Jurassic Park"}) assert result is not None assert result["year"] == 1993 # This will raise a type-checking error, despite being present, because it is added by Motor. assert result["_id"] # type:ignore[typeddict-item] ``` -------------------------------- ### Iterate Documents with async for Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-tornado.rst Handle one document at a time in an async for loop. You can apply sort, limit, or skip to a query before iterating. ```python async def do_find(): c = db.test_collection async for document in c.find({"i": {"$lt": 2}}): pprint.pprint(document) IOLoop.current().run_sync(do_find) ``` ```python async def do_find(): cursor = db.test_collection.find({"i": {"$lt": 4}}) # Modify the query before iterating cursor.sort("i", -1).skip(1).limit(2) async for document in cursor: pprint.pprint(document) IOLoop.current().run_sync(do_find) ``` -------------------------------- ### Run Motor Tests with Tox Source: https://github.com/mongodb/motor/blob/master/CONTRIBUTING.md Execute the 'test' module using tox. Ensure you have the desired Python version on your PATH. ```bash tox -m test ``` -------------------------------- ### Find Multiple Documents with Motor using to_list Source: https://github.com/mongodb/motor/blob/master/doc/tutorial-asyncio.rst Query for a set of documents and retrieve them as a list using 'find' and 'to_list'. 'find' does not require 'await', but 'to_list' does. A 'length' argument is required for 'to_list'. ```python async def do_find(): cursor = db.test_collection.find({"i": {"$lt": 5}}).sort("i") for document in await cursor.to_list(length=100): pprint.pprint(document) loop = client.get_io_loop() loop.run_until_complete(do_find()) ``` -------------------------------- ### Replace MotorCollection.initialize_unordered_bulk_op Source: https://github.com/mongodb/motor/blob/master/doc/migrate-to-motor-2.rst Use `bulk_write` for performing bulk write operations instead of the deprecated `initialize_unordered_bulk_op` and related methods. ```python collection.bulk_write([...]) ```