Skip to content

Commit afb6a93

Browse files
committed
PYTHON-1332 - Session param for client methods
1 parent 6ff5b78 commit afb6a93

File tree

2 files changed

+95
-20
lines changed

2 files changed

+95
-20
lines changed

pymongo/mongo_client.py

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,19 +1234,37 @@ def _return_server_session(self, server_session):
12341234
"""Internal: return a _ServerSession to the pool."""
12351235
return self._topology.return_server_session(server_session)
12361236

1237-
def server_info(self):
1238-
"""Get information about the MongoDB server we're connected to."""
1237+
def server_info(self, session=None):
1238+
"""Get information about the MongoDB server we're connected to.
1239+
1240+
:Parameters:
1241+
- `session` (optional): a
1242+
:class:`~pymongo.client_session.ClientSession`.
1243+
1244+
.. versionchanged:: 3.6
1245+
Added ``session`` parameter.
1246+
"""
12391247
return self.admin.command("buildinfo",
1240-
read_preference=ReadPreference.PRIMARY)
1248+
read_preference=ReadPreference.PRIMARY,
1249+
session=session)
1250+
1251+
def database_names(self, session=None):
1252+
"""Get a list of the names of all databases on the connected server.
1253+
1254+
:Parameters:
1255+
- `session` (optional): a
1256+
:class:`~pymongo.client_session.ClientSession`.
12411257
1242-
def database_names(self):
1243-
"""Get a list of the names of all databases on the connected server."""
1258+
.. versionchanged:: 3.6
1259+
Added ``session`` parameter.
1260+
"""
12441261
return [db["name"] for db in
12451262
self._database_default_options("admin").command(
12461263
SON([("listDatabases", 1),
1247-
("nameOnly", True)]))["databases"]]
1264+
("nameOnly", True)]),
1265+
session=session)["databases"]]
12481266

1249-
def drop_database(self, name_or_database):
1267+
def drop_database(self, name_or_database, session=None):
12501268
"""Drop a database.
12511269
12521270
Raises :class:`TypeError` if `name_or_database` is not an instance of
@@ -1257,6 +1275,11 @@ def drop_database(self, name_or_database):
12571275
- `name_or_database`: the name of a database to drop, or a
12581276
:class:`~pymongo.database.Database` instance representing the
12591277
database to drop
1278+
- `session` (optional): a
1279+
:class:`~pymongo.client_session.ClientSession`.
1280+
1281+
.. versionchanged:: 3.6
1282+
Added ``session`` parameter.
12601283
12611284
.. note:: The :attr:`~pymongo.mongo_client.MongoClient.write_concern` of
12621285
this client is automatically applied to this operation when using
@@ -1284,7 +1307,8 @@ def drop_database(self, name_or_database):
12841307
slave_ok=slave_ok,
12851308
read_preference=ReadPreference.PRIMARY,
12861309
write_concern=self.write_concern,
1287-
parse_write_concern_error=True)
1310+
parse_write_concern_error=True,
1311+
session=session)
12881312

12891313
def get_default_database(self):
12901314
"""DEPRECATED - Get the database named in the MongoDB connection URI.
@@ -1382,30 +1406,39 @@ def is_locked(self):
13821406
def fsync(self, **kwargs):
13831407
"""Flush all pending writes to datafiles.
13841408
1385-
:Parameters:
1386-
1387-
Optional parameters can be passed as keyword arguments:
1409+
Optional parameters can be passed as keyword arguments:
1410+
- `lock`: If True lock the server to disallow writes.
1411+
- `async`: If True don't block while synchronizing.
1412+
- `session` (optional): a
1413+
:class:`~pymongo.client_session.ClientSession`.
13881414
1389-
- `lock`: If True lock the server to disallow writes.
1390-
- `async`: If True don't block while synchronizing.
1415+
.. versionchanged:: 3.6
1416+
Added ``session`` parameter.
13911417
1392-
.. warning:: `async` and `lock` can not be used together.
1418+
.. warning:: `async` and `lock` can not be used together.
13931419
1394-
.. warning:: MongoDB does not support the `async` option
1395-
on Windows and will raise an exception on that
1396-
platform.
1420+
.. warning:: MongoDB does not support the `async` option
1421+
on Windows and will raise an exception on that
1422+
platform.
13971423
"""
13981424
self.admin.command("fsync",
13991425
read_preference=ReadPreference.PRIMARY, **kwargs)
14001426

1401-
def unlock(self):
1427+
def unlock(self, session=None):
14021428
"""Unlock a previously locked server.
1429+
1430+
:Parameters:
1431+
- `session` (optional): a
1432+
:class:`~pymongo.client_session.ClientSession`.
1433+
1434+
.. versionchanged:: 3.6
1435+
Added ``session`` parameter.
14031436
"""
14041437
cmd = {"fsyncUnlock": 1}
14051438
with self._socket_for_writes() as sock_info:
14061439
if sock_info.max_wire_version >= 4:
14071440
try:
1408-
sock_info.command("admin", cmd)
1441+
sock_info.command("admin", cmd, session=session)
14091442
except OperationFailure as exc:
14101443
# Ignore "DB not locked" to replicate old behavior
14111444
if exc.code != 125:

test/test_session.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
"""Test the client_session module."""
1616
from bson import DBRef
1717
from pymongo import OFF, InsertOne, IndexModel
18-
from pymongo.errors import InvalidOperation, ConfigurationError
18+
from pymongo.errors import (ConfigurationError,
19+
InvalidOperation,
20+
OperationFailure)
1921
from pymongo.monitoring import _SENSITIVE_COMMANDS
2022
from test import IntegrationTest, client_context
2123
from test.utils import ignore_deprecations, rs_or_single_client, EventListener
@@ -74,6 +76,46 @@ def test_sessions_not_supported(self):
7476
ConfigurationError, "Sessions are not supported"):
7577
self.client.start_session()
7678

79+
@client_context.require_sessions
80+
def test_client(self):
81+
listener = SessionTestListener()
82+
client = rs_or_single_client(event_listeners=[listener])
83+
84+
# Make sure if the test fails we unlock the server.
85+
def unlock():
86+
try:
87+
client.unlock()
88+
except OperationFailure:
89+
pass
90+
91+
self.addCleanup(unlock)
92+
93+
ops = [
94+
(client.server_info, [], {}),
95+
(client.database_names, [], {}),
96+
(client.drop_database, ['pymongo_test'], {}),
97+
(client.fsync, [], {'lock': True}),
98+
(client.unlock, [], {}),
99+
]
100+
101+
with client.start_session() as s:
102+
for f, args, kwargs in ops:
103+
listener.results.clear()
104+
kwargs['session'] = s
105+
f(*args, **kwargs)
106+
self.assertGreaterEqual(len(listener.results['started']), 1)
107+
for event in listener.results['started']:
108+
self.assertTrue(
109+
'lsid' in event.command,
110+
"%s sent no lsid with %s" % (
111+
f.__name__, event.command_name))
112+
113+
self.assertEqual(
114+
s.session_id,
115+
event.command['lsid'],
116+
"%s sent wrong lsid with %s" % (
117+
f.__name__, event.command_name))
118+
77119
@client_context.require_sessions
78120
def test_database(self):
79121
listener = SessionTestListener()

0 commit comments

Comments
 (0)