Skip to content

Commit 09edbe2

Browse files
authored
Merge from dev to master to create release 0.0.33 (#245, #232)
* Fixed concat issue with plus(or other symbols) in filename(#245) * Added readinto method(#232) * Changed api-version to 2018-05-01.
1 parent 1f9fe18 commit 09edbe2

File tree

5 files changed

+90
-29
lines changed

5 files changed

+90
-29
lines changed

HISTORY.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
Release History
44
===============
55

6+
0.0.33 (2018-10-015)
7+
+++++++++++++++++++
8+
* Fixed concat issue with plus(or other symbols) in filename
9+
* Added readinto method
10+
* Changed api-version to 2018-05-01 for all.
11+
612
0.0.32 (2018-10-04)
713
+++++++++++++++++++
814
* Fixed test bug

azure/datalake/store/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# license information.
77
# --------------------------------------------------------------------------
88

9-
__version__ = "0.0.32"
9+
__version__ = "0.0.33"
1010

1111
from .core import AzureDLFileSystem
1212
from .multithread import ADLDownloader

azure/datalake/store/core.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import sys
2121
import time
2222
import uuid
23+
import json
2324

2425

2526
# local imports
@@ -540,11 +541,14 @@ def concat(self, outfile, filelist, delete_source=False):
540541
directory, and delete that whole directory when done.
541542
"""
542543
outfile = AzureDLPath(outfile).trim()
543-
filelist = ','.join(AzureDLPath(f).as_posix() for f in filelist)
544544
delete = 'true' if delete_source else 'false'
545+
sourceList = [AzureDLPath(f).as_posix() for f in filelist]
546+
sources = {}
547+
sources["sources"] = sourceList
545548
self.azure.call('MSCONCAT', outfile.as_posix(),
546-
data='sources='+filelist,
547-
deleteSourceDirectory=delete)
549+
data=bytearray(json.dumps(sources,separators=(',', ':')), encoding="utf-8"),
550+
deleteSourceDirectory=delete,
551+
headers={'Content-Type': "application/json"},)
548552
self.invalidate_cache(outfile)
549553

550554
merge = concat
@@ -858,6 +862,20 @@ def read(self, length=-1):
858862

859863
read1 = read
860864

865+
def readinto(self, b):
866+
"""
867+
Reads data into buffer b
868+
Returns number of bytes read.
869+
870+
Parameters
871+
----------
872+
b : bytearray
873+
Buffer to which bytes are read into
874+
"""
875+
temp = self.read(len(b))
876+
b[:len(temp)] = temp
877+
return len(temp)
878+
861879
def write(self, data):
862880
"""
863881
Write data to buffer.

azure/datalake/store/lib.py

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ class DatalakeRESTInterface:
211211
url_suffix: str (None)
212212
Domain to send REST requests to. The end-point URL is constructed
213213
using this and the store_name. If None, use default.
214-
api_version: str (2016-11-01)
214+
api_version: str (2018-05-01)
215215
The API version to target with requests. Changing this value will
216216
change the behavior of the requests, and can cause unexpected behavior or
217217
breaking changes. Changes to this value should be undergone with caution.
@@ -246,7 +246,7 @@ class DatalakeRESTInterface:
246246
}
247247

248248
def __init__(self, store_name=default_store, token=None,
249-
url_suffix=default_adls_suffix, api_version='2016-11-01', **kwargs):
249+
url_suffix=default_adls_suffix, api_version='2018-05-01', **kwargs):
250250
# in the case where an empty string is passed for the url suffix, it must be replaced with the default.
251251
url_suffix = url_suffix or default_adls_suffix
252252
self.local = threading.local()
@@ -288,7 +288,7 @@ def _check_token(self):
288288
self.head = {'Authorization': cur_session.headers['Authorization']}
289289
self.local.session = None
290290

291-
def _log_request(self, method, url, op, path, params, headers, retry_count):
291+
def _log_request(self, method, url, op, path, params, headers, retry_count):
292292
msg = "HTTP Request\n{} {}\n".format(method.upper(), url)
293293
msg += "{} '{}' {}\n\n".format(
294294
op, path,
@@ -334,7 +334,7 @@ def _is_json_response(self, response):
334334
return False
335335
return response.headers['content-type'].startswith('application/json')
336336

337-
def call(self, op, path='', is_extended=False, expected_error_code=None, retry_policy=None, **kwargs):
337+
def call(self, op, path='', is_extended=False, expected_error_code=None, retry_policy=None, headers = {}, **kwargs):
338338
""" Execute a REST call
339339
340340
Parameters
@@ -389,15 +389,16 @@ def call(self, op, path='', is_extended=False, expected_error_code=None, retry_p
389389
retry_count += 1
390390
last_exception = None
391391
try:
392-
response = self.__call_once(method,
393-
url,
394-
params,
395-
data,
396-
stream,
397-
request_id,
398-
retry_count,
399-
op,
400-
path,
392+
response = self.__call_once(method=method,
393+
url=url,
394+
params=params,
395+
data=data,
396+
stream=stream,
397+
request_id=request_id,
398+
retry_count=retry_count,
399+
op=op,
400+
path=path,
401+
headers=headers,
401402
**kwargs)
402403
except requests.exceptions.RequestException as e:
403404
last_exception = e
@@ -449,13 +450,14 @@ def is_successful_response(self, response, exception):
449450
return True
450451
return False
451452

452-
def __call_once(self, method, url, params, data, stream, request_id, retry_count, op, path='', **kwargs):
453+
def __call_once(self, method, url, params, data, stream, request_id, retry_count, op, path='', headers={}, **kwargs):
453454
func = getattr(self.session, method)
454-
headers = self.head.copy()
455-
headers['x-ms-client-request-id'] = request_id + "." + str(retry_count)
456-
headers['User-Agent'] = self.user_agent
457-
self._log_request(method, url, op, urllib.quote(path), kwargs, headers, retry_count)
458-
return func(url, params=params, headers=headers, data=data, stream=stream)
455+
req_headers = self.head.copy()
456+
req_headers['x-ms-client-request-id'] = request_id + "." + str(retry_count)
457+
req_headers['User-Agent'] = self.user_agent
458+
req_headers.update(headers)
459+
self._log_request(method, url, op, urllib.quote(path), kwargs, req_headers, retry_count)
460+
return func(url, params=params, headers=req_headers, data=data, stream=stream)
459461

460462
def __getstate__(self):
461463
state = self.__dict__.copy()

tests/test_core.py

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,18 +145,21 @@ def test_seek(azure):
145145

146146
@my_vcr.use_cassette
147147
def test_concat(azure):
148-
with azure.open(a, 'wb') as f:
148+
aplus = a + "+file1"
149+
bplus = b + "+file2"
150+
cplus = c + "+res"
151+
with azure.open(aplus, 'wb') as f:
149152
f.write(b'hello ')
150-
with azure.open(b, 'wb') as f:
153+
with azure.open(bplus, 'wb') as f:
151154
f.write(b'world')
152155
try:
153-
azure.rm(c)
156+
azure.rm(cplus)
154157
except:
155158
pass
156-
azure.concat(c, [a, b])
157159

158-
out = azure.cat(c)
159-
azure.rm(c)
160+
azure.concat(cplus, [aplus, bplus])
161+
out = azure.cat(cplus)
162+
azure.rm(cplus)
160163

161164
assert out == b'hello world'
162165

@@ -453,6 +456,38 @@ def test_full_read(azure):
453456
assert f.read(4) == b'789'
454457
assert f.tell() == 10
455458

459+
@my_vcr.use_cassette
460+
def test_readinto(azure):
461+
with azure_teardown(azure):
462+
with azure.open(a, 'wb') as f:
463+
f.write(b'0123456789')
464+
465+
with azure.open(a, 'rb') as f:
466+
buffer = bytearray(6)
467+
l = f.readinto(buffer)
468+
assert l == 6
469+
assert buffer == b'012345'
470+
471+
buffer = bytearray(6)
472+
l = f.readinto(buffer)
473+
assert l == 4
474+
assert buffer == b'6789\x00\x00'
475+
476+
buffer = bytearray(6)
477+
l = f.readinto(buffer)
478+
assert buffer == b'\x00\x00\x00\x00\x00\x00'
479+
assert l == 0
480+
481+
with azure.open(a, 'rb') as f:
482+
buffer = bytearray(6)
483+
l = f.readinto(buffer)
484+
assert l == 6
485+
assert buffer == b'012345'
486+
487+
l = f.readinto(buffer)
488+
assert l == 4
489+
assert buffer == b'678945' # 45 from previous buffer fill should not be overwritten
490+
456491

457492
@my_vcr.use_cassette
458493
def test_filename_specialchar(azure):

0 commit comments

Comments
 (0)