Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Object Store Get & API Cleanup #443

Merged
merged 1 commit into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 51 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ A locally-focused workflow (local development, local execution) with the CLI may
- [`lean cloud object-store get`](#lean-cloud-object-store-get)
- [`lean cloud object-store list`](#lean-cloud-object-store-list)
- [`lean cloud object-store ls`](#lean-cloud-object-store-ls)
- [`lean cloud object-store properties`](#lean-cloud-object-store-properties)
- [`lean cloud object-store set`](#lean-cloud-object-store-set)
- [`lean cloud optimize`](#lean-cloud-optimize)
- [`lean cloud pull`](#lean-cloud-pull)
Expand Down Expand Up @@ -112,6 +113,7 @@ A locally-focused workflow (local development, local execution) with the CLI may
- [`lean object-store get`](#lean-object-store-get)
- [`lean object-store list`](#lean-object-store-list)
- [`lean object-store ls`](#lean-object-store-ls)
- [`lean object-store properties`](#lean-object-store-properties)
- [`lean object-store set`](#lean-object-store-set)
- [`lean optimize`](#lean-optimize)
- [`lean project-create`](#lean-project-create)
Expand Down Expand Up @@ -450,6 +452,8 @@ Usage: lean cloud object-store delete [OPTIONS] KEY

Delete a value from the organization's cloud object store.

:param key: The desired key name to delete.

Options:
--verbose Enable debug logging
--help Show this message and exit.
Expand All @@ -459,16 +463,20 @@ _See code: [lean/commands/cloud/object_store/delete.py](lean/commands/cloud/obje

### `lean cloud object-store get`

Get a value from the organization's cloud object store.
Download an object store value to disk from the organization's cloud object store.

```
Usage: lean cloud object-store get [OPTIONS] KEY
Usage: lean cloud object-store get [OPTIONS] [KEY]...

Download an object store value to disk from the organization's cloud object store.

Get a value from the organization's cloud object store.
:param key: The desired key to fetch, multiple can be provided.

Options:
--verbose Enable debug logging
--help Show this message and exit.
--destination-folder TEXT The destination folder to download the object store values, if not provided will use to
current directory
--verbose Enable debug logging
--help Show this message and exit.
```

_See code: [lean/commands/cloud/object_store/get.py](lean/commands/cloud/object_store/get.py)_
Expand All @@ -482,6 +490,8 @@ Usage: lean cloud object-store list [OPTIONS] [KEY]

List all values for the given root key in the organization's cloud object store.

:param key: The desired root key to list.

Options:
--verbose Enable debug logging
--help Show this message and exit.
Expand All @@ -498,13 +508,33 @@ Usage: lean cloud object-store ls [OPTIONS] [KEY]

List all values for the given root key in the organization's cloud object store.

:param key: The desired root key to list.

Options:
--verbose Enable debug logging
--help Show this message and exit.
```

_See code: [lean/commands/cloud/object_store/ls.py](lean/commands/cloud/object_store/ls.py)_

### `lean cloud object-store properties`

Get a value properties from the organization's cloud object store.

```
Usage: lean cloud object-store properties [OPTIONS] KEY

Get a value properties from the organization's cloud object store.

:param key: The desired key to fetch the properties for.

Options:
--verbose Enable debug logging
--help Show this message and exit.
```

_See code: [lean/commands/cloud/object_store/properties.py](lean/commands/cloud/object_store/properties.py)_

### `lean cloud object-store set`

Sets the data to the given key in the organization's cloud object store.
Expand Down Expand Up @@ -1427,6 +1457,22 @@ Options:

_See code: [lean/commands/object_store/ls.py](lean/commands/object_store/ls.py)_

### `lean object-store properties`

Opens the local storage directory in the file explorer.

```
Usage: lean object-store properties [OPTIONS]

Opens the local storage directory in the file explorer.

Options:
--verbose Enable debug logging
--help Show this message and exit.
```

_See code: [lean/commands/object_store/properties.py](lean/commands/object_store/properties.py)_

### `lean object-store set`

Opens the local storage directory in the file explorer.
Expand Down
3 changes: 2 additions & 1 deletion lean/commands/cloud/object_store/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
from lean.commands.cloud.object_store.set import set
from lean.commands.cloud.object_store.list import list
from lean.commands.cloud.object_store.delete import delete
from lean.commands.cloud.object_store.properties import properties

object_store.add_command(get)
object_store.add_command(set)
object_store.add_command(list)
object_store.add_command(delete)

object_store.add_command(properties)
5 changes: 3 additions & 2 deletions lean/commands/cloud/object_store/delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@
def delete(key: str) -> str:
"""
Delete a value from the organization's cloud object store.


:param key: The desired key name to delete.
"""
organization_id = container.organization_manager.try_get_working_organization_id()
api_client = container.api_client
api_client.object_store.delete(key, organization_id)
api_client.object_store.delete(key, organization_id)
63 changes: 34 additions & 29 deletions lean/commands/cloud/object_store/get.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,45 +11,50 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from click import command, argument
from uuid import uuid4
from os import path, getcwd, unlink, mkdir

from click import command, option, argument
from lean.click import LeanCommand
from lean.container import container


@command(cls=LeanCommand)
@argument("key", type=str)
def get(key: str) -> str:
@argument("key", type=str, nargs=-1)
@option("--destination-folder", type=str, default="",
help=f"The destination folder to download the object store values,"
f" if not provided will use to current directory")
def get(key: [str], destination_folder: str):
"""
Get a value from the organization's cloud object store.
Download an object store value to disk from the organization's cloud object store.

:param key: The desired key to fetch, multiple can be provided.
"""
organization_id = container.organization_manager.try_get_working_organization_id()
api_client = container.api_client
logger = container.logger
data = api_client.object_store.get(key, organization_id)

try:
headers = ["size", "modified", "key", "preview"]
display_headers = ["Bytes", "Modified", "Filename", "Preview"]
data_row = []
for header in headers:
if header == "preview":
value = str(data["metadata"].get(header, "N/A"))
data_row.append(_clean_up_preview(value))
else:
value = str(data["metadata"].get(header, ""))
data_row.append(value)
all_rows = [display_headers] + [data_row]
column_widths = [max(len(row[i]) for row in all_rows) for i in range(len(all_rows[0]))]
for row in all_rows:
logger.info(" ".join(value.ljust(width) for value, width in zip(row, column_widths)))
except KeyError as e:
logger.error(f"Key {key} not found.")
except Exception as e:
logger.error(f"Error: {e}")


def _clean_up_preview(preview: str) -> str:
return preview.rstrip()[:10]

logger.info(f"Fetching object store download url")
url = api_client.object_store.get(key, organization_id, logger)
if not destination_folder:
destination_folder = getcwd()

if not path.exists(destination_folder):
mkdir(destination_folder)

temp_file = path.join(destination_folder, f"{str(uuid4())}.zip")

with logger.transient_progress() as progress:
progress.add_task(f"Start downloading keys into {temp_file}:", total=None)
logger.debug(f"Downloading: {url}")

api_client.data.download_url(url, temp_file, lambda advance: None)

logger.info(f"Unzipping object store keys values into: '{destination_folder}'")
from zipfile import ZipFile
with ZipFile(temp_file, 'r') as zip_ref:
zip_ref.extractall(destination_folder)

if path.exists(temp_file):
logger.debug(f"Deleting temp file: '{temp_file}'")
unlink(temp_file)
6 changes: 4 additions & 2 deletions lean/commands/cloud/object_store/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@

@object_store.command(cls=LeanCommand, name="list", aliases=["ls"])
@argument("key", type=str, default="/")
def list(key: str) -> str:
def list(key: str):
"""
List all values for the given root key in the organization's cloud object store.

:param key: The desired root key to list.
"""
organization_id = container.organization_manager.try_get_working_organization_id()
api_client = container.api_client
Expand All @@ -41,4 +43,4 @@ def list(key: str) -> str:
except KeyError as e:
logger.error(f"Key {key} not found.")
except Exception as e:
logger.error(f"Error: {e}")
logger.error(f"Error: {e}")
54 changes: 54 additions & 0 deletions lean/commands/cloud/object_store/properties.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
# Lean CLI v1.0. Copyright 2021 QuantConnect Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from click import command, argument
from lean.click import LeanCommand
from lean.container import container


@command(cls=LeanCommand)
@argument("key", type=str)
def properties(key: str):
"""
Get a value properties from the organization's cloud object store.

:param key: The desired key to fetch the properties for.
"""
organization_id = container.organization_manager.try_get_working_organization_id()
api_client = container.api_client
logger = container.logger
data = api_client.object_store.properties(key, organization_id)

try:
headers = ["size", "modified", "key", "preview"]
display_headers = ["Bytes", "Modified", "Filename", "Preview"]
data_row = []
for header in headers:
if header == "preview":
value = str(data["metadata"].get(header, "N/A"))
data_row.append(_clean_up_preview(value))
else:
value = str(data["metadata"].get(header, ""))
data_row.append(value)
all_rows = [display_headers] + [data_row]
column_widths = [max(len(row[i]) for row in all_rows) for i in range(len(all_rows[0]))]
for row in all_rows:
logger.info(" ".join(value.ljust(width) for value, width in zip(row, column_widths)))
except KeyError as e:
logger.error(f"Key {key} not found.")
except Exception as e:
logger.error(f"Error: {e}")


def _clean_up_preview(preview: str) -> str:
return preview.rstrip()[:10]
2 changes: 1 addition & 1 deletion lean/commands/cloud/object_store/set.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ def set(key: str, path: Path) -> None:
api_client = container.api_client
with open(path, "rb") as file:
bytes_data: bytes = file.read()
api_client.object_store.set(key, bytes_data, organization_id)
api_client.object_store.set(key, bytes_data, organization_id)
3 changes: 2 additions & 1 deletion lean/commands/object_store/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
from lean.commands.object_store.set import set
from lean.commands.object_store.list import list
from lean.commands.object_store.delete import delete
from lean.commands.object_store.properties import properties

object_store.add_command(get)
object_store.add_command(set)
object_store.add_command(list)
object_store.add_command(delete)

object_store.add_command(properties)
26 changes: 26 additions & 0 deletions lean/commands/object_store/properties.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
# Lean CLI v1.0. Copyright 2021 QuantConnect Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


from click import command
from lean.click import LeanCommand
from lean.container import container
from lean.components.util.object_store_helper import open_storage_directory_in_explorer


@command(cls=LeanCommand)
def properties() -> str:
"""
Opens the local storage directory in the file explorer.
"""
open_storage_directory_in_explorer(container.lean_config_manager)
Loading
Loading