Skip to content

Commit

Permalink
Deprecate blobs_get and open blobs_get_v2 (#183)
Browse files Browse the repository at this point in the history
* adding new endpoint in preparation for deprecating + test

* iteration on comments

* fixing tests

* adding docstrings and testing for validate_path

* swapping to v1 route instead of beta

* changelog
  • Loading branch information
ddl-giuliocapolino committed Nov 28, 2023
1 parent 14a762c commit d361b6f
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ All notable changes to the `python-domino` library will be documented in this fi
## [Unreleased]
### Added
* Updated Apps documentation
* Added get_blobs_v2 endpoint plus tests

### Changed
* Marked get_blobs endpoint as deprecated

## 1.2.4

Expand Down
4 changes: 2 additions & 2 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -481,10 +481,10 @@ print file['path'], '->', file['url']
print(files)
# Get the content (i.e. blob) for the file you're interested in.
# blobs_get returns a connection rather than the content, because
# blobs_get_v2 returns a connection rather than the content, because
# the content can get quite large and it's up to you how you want
# to handle it
print(domino.blobs_get(files[0]['key']).read())
print(domino.blobs_get_v2(files[0]['path'], commitId, domino.project_id).read())
# Start a run of file main.py using the latest copy of that file
domino.runs_start(["main.py", "arg1", "arg2"])
Expand Down
35 changes: 35 additions & 0 deletions domino/domino.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import re
import time
from typing import List, Optional, Tuple
import warnings

import polling2
import requests
Expand Down Expand Up @@ -684,10 +685,23 @@ def files_upload(self, path, file):
return self._put_file(url, file)

def blobs_get(self, key):
"""
Deprecated. Use blobs_get_v2(path, commit_id, project_id) instead
:param key: blob key
:return: blob content
"""
message = "blobs_get is deprecated and will soon be removed. Please migrate to blobs_get_v2 and adjust the " \
"input parameters accordingly "
warnings.warn(message, DeprecationWarning)
self._validate_blob_key(key)
url = self._routes.blobs_get(key)
return self.request_manager.get_raw(url)

def blobs_get_v2(self, path, commit_id, project_id):
self._validate_blob_path(path)
url = self._routes.blobs_get_v2(path, commit_id, project_id)
return self.request_manager.get_raw(url)

def fork_project(self, target_name):
url = self._routes.fork_project(self.project_id)
request = {"name": target_name}
Expand Down Expand Up @@ -1203,6 +1217,27 @@ def _validate_blob_key(key):
)
)

@staticmethod
def _validate_blob_path(path):
"""
Helper method to validate that the path is normalized
For example: A//B, A/B/, A/./B and A/foo/../B are not normalized/canonical, whereas A/B is.
Args:
path: the string of the path to check
Return:
None, however, it throws a MalformedInputException if the input is not normalized/canonical.
"""
normalized_path = os.path.normpath(path)
if path != normalized_path:
raise exceptions.MalformedInputException(
(
"Path should be normalized and cannot contain "
"'..' or '../'. "
)
)

@staticmethod
def _validate_information_data_type(info: dict):
accepted_units = {"GiB": True, "MB": True}
Expand Down
9 changes: 9 additions & 0 deletions domino/routes.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import warnings

class _Routes:
def __init__(self, host, owner_username, project_name):
self.host = host
Expand Down Expand Up @@ -71,9 +73,16 @@ def files_upload(self, path):
def commits_list(self):
return self._build_project_url() + "/commits"

# Deprecated - use blobs_get_v2 instead
def blobs_get(self, key):
message = "blobs_get is deprecated and will soon be removed. Please migrate to blobs_get_v2 and adjust the " \
"input parameters accordingly "
warnings.warn(message, DeprecationWarning)
return self._build_project_url() + "/blobs/" + key

def blobs_get_v2(self, path, commit_id, project_id):
return self.host + f"/api/projects/v1/projects/{project_id}/files/{commit_id}/{path}/content"

def fork_project(self, project_id):
return self.host + f"/v4/projects/{project_id}/fork"

Expand Down
2 changes: 1 addition & 1 deletion examples/upload_and_run_file_and_download_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def download_results(domino, commitId, results, output, exp):
output = ""

for d in download:
url = domino.blobs_get(d["key"])
url = domino.blobs_get_v2(d["path"], commitId, domino.project_id)
file_to_write = ""

# if we have multiple files, then output is a directory
Expand Down
37 changes: 36 additions & 1 deletion tests/test_projects.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import uuid
from pprint import pformat

import gzip
import pytest

from domino import Domino
from domino import Domino, exceptions
from domino.exceptions import ProjectNotFoundException
from domino.helpers import domino_is_reachable

Expand Down Expand Up @@ -120,6 +121,40 @@ def test_get_file_from_a_project(default_domino_client):
), f"Unable to get .dominoignore file\n{str(file_contents)}"


@pytest.mark.skipif(
not domino_is_reachable(), reason="No access to a live Domino deployment"
)
def test_get_file_from_a_project_v2(default_domino_client):
"""
Confirm that the python-domino client can download a file from a project in the v2 endpoint
"""
commits_list = default_domino_client.commits_list()
files_list = default_domino_client.files_list(commits_list[0])

for file in files_list["data"]:
if file["path"] == ".dominoignore":
file_contents = default_domino_client.blobs_get_v2(file["path"], commits_list[0], default_domino_client.project_id).read()
break

assert "ignore certain files" in str(
file_contents
), f"Unable to get .dominoignore file\n{str(file_contents)}"


@pytest.mark.skipif(
not domino_is_reachable(), reason="No access to a live Domino deployment"
)
def test_get_blobs_v2_non_canonical(default_domino_client):
"""
Confirm that the python-domino client get_blobs_v2 will fail if input path is non-canonical
"""
non_canonical_path = "/domino/mnt/../test.py"
commits_list = default_domino_client.commits_list()

with pytest.raises(exceptions.MalformedInputException):
default_domino_client.blobs_get_v2(non_canonical_path, commits_list[0], default_domino_client.project_id).read()


@pytest.mark.skipif(
not domino_is_reachable(), reason="No access to a live Domino deployment"
)
Expand Down

0 comments on commit d361b6f

Please sign in to comment.