Skip to content

Commit 275d20a

Browse files
authored
Merge pull request #143 from mfulleratlassian/Issue142
Issue 142 - Allow users to provide a botocore session on creation of S3FileSystem
2 parents df620c1 + daf4bcf commit 275d20a

File tree

2 files changed

+56
-6
lines changed

2 files changed

+56
-6
lines changed

s3fs/core.py

+20-6
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ class S3FileSystem(object):
119119
objects.
120120
config_kwargs : dict of parameters passed to ``botocore.client.Config``
121121
kwargs : other parameters for boto3 session
122+
session : botocore Session object to be used for all connections.
123+
This session will be used inplace of creating a new session inside S3FileSystem.
124+
122125
123126
Examples
124127
--------
@@ -140,9 +143,12 @@ def __init__(self, anon=False, key=None, secret=None, token=None,
140143
use_ssl=True, client_kwargs=None, requester_pays=False,
141144
default_block_size=None, default_fill_cache=True,
142145
version_aware=False, config_kwargs=None,
143-
s3_additional_kwargs=None, **kwargs):
146+
s3_additional_kwargs=None, session=None, **kwargs):
144147
self.anon = anon
145148
self.session = None
149+
self.passed_in_session = session
150+
if self.passed_in_session:
151+
self.session = self.passed_in_session
146152
self.key = key
147153
self.secret = secret
148154
self.token = token
@@ -205,7 +211,7 @@ def connect(self, refresh=False):
205211
anon, key, secret, kwargs, ckwargs, token, ssl = (
206212
self.anon, self.key, self.secret, self.kwargs,
207213
self.client_kwargs, self.token, self.use_ssl)
208-
214+
209215
# Include the current PID in the connection key so that different
210216
# SSL connections are made for each process.
211217
tok = tokenize(anon, key, secret, kwargs, ckwargs, token,
@@ -214,24 +220,30 @@ def connect(self, refresh=False):
214220
self._conn.pop(tok, None)
215221
if tok not in self._conn:
216222
logger.debug("Open S3 connection. Anonymous: %s", self.anon)
223+
217224
if self.anon:
218225
from botocore import UNSIGNED
219226
conf = Config(connect_timeout=self.connect_timeout,
220227
read_timeout=self.read_timeout,
221228
signature_version=UNSIGNED, **self.config_kwargs)
222-
self.session = boto3.Session(**self.kwargs)
229+
if not self.passed_in_session:
230+
self.session = boto3.Session(**self.kwargs)
223231
else:
224232
conf = Config(connect_timeout=self.connect_timeout,
225233
read_timeout=self.read_timeout,
226234
**self.config_kwargs)
227-
self.session = boto3.Session(self.key, self.secret, self.token,
228-
**self.kwargs)
235+
if not self.passed_in_session:
236+
self.session = boto3.Session(self.key, self.secret, self.token,
237+
**self.kwargs)
238+
229239
s3 = self.session.client('s3', config=conf, use_ssl=ssl,
230240
**self.client_kwargs)
231241
self._conn[tok] = (s3, self.session)
232242
else:
233243
s3, session = self._conn[tok]
234-
self.session = session
244+
if not self.passed_in_session:
245+
self.session = session
246+
235247
return s3
236248

237249
def get_delegated_s3pars(self, exp=3600):
@@ -260,6 +272,8 @@ def get_delegated_s3pars(self, exp=3600):
260272
'token': cred['SessionToken'], 'anon': False}
261273

262274
def __getstate__(self):
275+
if self.passed_in_session:
276+
raise NotImplementedError
263277
d = self.__dict__.copy()
264278
del d['s3']
265279
del d['session']

s3fs/tests/test_s3fs.py

+36
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from s3fs.core import S3FileSystem
1010
from s3fs.utils import seek_delimiter, ignoring, SSEParams
1111
import moto
12+
import boto3
1213

1314
from botocore.exceptions import NoCredentialsError
1415

@@ -1114,3 +1115,38 @@ def test_change_defaults_only_subsequent(monkeypatch):
11141115
# Test the other file systems created to see if their block sizes changed
11151116
assert fs_overridden.default_block_size == 64 * (1024 ** 2)
11161117
assert fs_default.default_block_size == 5 * (1024 ** 2)
1118+
1119+
1120+
1121+
def test_passed_in_session_set_correctly(s3):
1122+
session = boto3.session.Session()
1123+
s3 = S3FileSystem(session=session)
1124+
assert s3.passed_in_session is session
1125+
client = s3.connect()
1126+
assert s3.session is session
1127+
1128+
1129+
def test_without_passed_in_session_set_unique(s3):
1130+
session = boto3.session.Session()
1131+
s3 = S3FileSystem()
1132+
assert s3.passed_in_session is None
1133+
client = s3.connect()
1134+
assert s3.session is not session
1135+
1136+
1137+
def test_pickle_without_passed_in_session(s3):
1138+
s3 = S3FileSystem()
1139+
try:
1140+
s3.__getstate__()
1141+
except NotImplementedError:
1142+
pytest.fail("Unexpected NotImplementedError")
1143+
1144+
1145+
def test_pickle_with_passed_in_session(s3):
1146+
session = boto3.session.Session()
1147+
s3 = S3FileSystem(session=session)
1148+
with pytest.raises(NotImplementedError):
1149+
s3.__getstate__()
1150+
1151+
1152+

0 commit comments

Comments
 (0)