Skip to content

Commit 2072279

Browse files
committed
add getContents endpoint
1 parent 11585dc commit 2072279

File tree

4 files changed

+72
-7
lines changed

4 files changed

+72
-7
lines changed

jupyter_drives/handlers.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,17 +69,17 @@ def initialize(self, logger: logging.Logger, manager: JupyterDrivesManager):
6969
return super().initialize(logger, manager)
7070

7171
@tornado.web.authenticated
72-
async def get(self, path: str = "", drive: str = ""):
72+
async def get(self, drive: str = "", path: str = ""):
7373
result = await self._manager.get_contents(drive, path)
7474
self.finish(result)
7575

7676
@tornado.web.authenticated
77-
async def post(self, path: str = "", drive: str = ""):
77+
async def post(self, drive: str = "", path: str = ""):
7878
result = await self._manager.new_file(drive, path)
7979
self.finish(result)
8080

8181
@tornado.web.authenticated
82-
async def patch(self, path: str = "", drive: str = ""):
82+
async def patch(self, drive: str = "", path: str = ""):
8383
body = self.get_json_body()
8484
result = await self._manager.rename_file(drive, path, **body)
8585
self.finish(result)

jupyter_drives/manager.py

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import logging
44
from typing import Dict, List, Optional, Tuple, Union, Any
55

6+
import os
67
import tornado
78
import httpx
89
import traitlets
@@ -11,6 +12,7 @@
1112
import obstore as obs
1213
from libcloud.storage.types import Provider
1314
from libcloud.storage.providers import get_driver
15+
import pyarrow
1416

1517
from .log import get_logger
1618
from .base import DrivesConfig
@@ -153,14 +155,63 @@ async def unmount_drive(self, drive_name: str):
153155

154156
return
155157

156-
async def get_contents(self, drive_name, path, **kwargs):
158+
async def get_contents(self, drive_name, path):
157159
"""Get contents of a file or directory.
158160
159161
Args:
160162
drive_name: name of drive to get the contents of
161-
path: path to file or directory
163+
path: path to file or directory (empty string for root listing)
162164
"""
163-
print('Get contents function called.')
165+
print('!!!!!!!!!!!!!!!!!!!', drive_name, 'path: ', path)
166+
if path == '/':
167+
path = ''
168+
drive_name = 'jupyter-drives-test-bucket-1'
169+
try :
170+
currentObject = os.path.basename(path) if os.path.basename(path) is not None else ''
171+
print('currentObject: ', currentObject)
172+
# check if we are listing contents of a directory
173+
if currentObject.find('.') == -1:
174+
print('in if')
175+
print('store: ', self._content_managers)
176+
data = []
177+
# using Arrow lists as they are recommended for large results
178+
# sream will be an async iterable of RecordBatch
179+
stream = obs.list(self._content_managers[drive_name], path, chunk_size=100, return_arrow=True)
180+
async for batch in stream:
181+
contents_list = pyarrow.record_batch(batch).to_pylist()
182+
for object in contents_list:
183+
data.append({
184+
"path": object["path"],
185+
"last_modified": object["last_modified"].isoformat(),
186+
"size": object["size"],
187+
})
188+
else:
189+
content = b""
190+
# retrieve contents of object
191+
obj = await obs.get_async(self._content_managers[drive_name], path)
192+
stream = obj.stream(min_chunk_size=5 * 1024 * 1024) # 5MB sized chunks
193+
async for buf in stream:
194+
content += buf
195+
196+
# retrieve metadata of object
197+
metadata = await obs.head_async(self._content_managers[drive_name], path)
198+
data = {
199+
"path": path,
200+
"content": content,
201+
"last_modified": metadata["last_modified"].isoformat(),
202+
"size": metadata["size"]
203+
}
204+
print(data)
205+
response = {
206+
"data": data
207+
}
208+
except Exception as e:
209+
raise tornado.web.HTTPError(
210+
status_code= httpx.codes.BAD_REQUEST,
211+
reason=f"The following error occured when retrieving the contents: {e}",
212+
)
213+
214+
return response
164215

165216
async def new_file(self, drive_name, path, **kwargs):
166217
"""Create a new file or directory at the given path.

src/contents.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Signal, ISignal } from '@lumino/signaling';
55
import { Contents, ServerConnection } from '@jupyterlab/services';
66
import { PathExt } from '@jupyterlab/coreutils';
77
import { IDriveInfo } from './token';
8-
import { mountDrive } from './requests';
8+
import { getContents, mountDrive } from './requests';
99

1010
let data: Contents.IModel = {
1111
name: '',
@@ -206,6 +206,9 @@ export class Drive implements Contents.IDrive {
206206
}
207207
}
208208

209+
const resp = await getContents(currentDrive.name, { path: '' });
210+
console.log('resp: ', resp);
211+
209212
data = {
210213
name: PathExt.basename(localPath),
211214
path: PathExt.basename(localPath),

src/requests.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { ReadonlyJSONObject } from '@lumino/coreutils';
2+
23
import { requestAPI } from './handler';
34

45
/**
@@ -24,3 +25,13 @@ export async function mountDrive(
2425
};
2526
return await requestAPI<any>('drives', 'POST', body);
2627
}
28+
29+
export async function getContents(
30+
driveName: string,
31+
options: { path: string }
32+
) {
33+
return await requestAPI<any>(
34+
'drives/' + driveName + '/' + options.path,
35+
'GET'
36+
);
37+
}

0 commit comments

Comments
 (0)