Skip to content

Commit

Permalink
Merge branch 'main' into delete-many
Browse files Browse the repository at this point in the history
  • Loading branch information
anish29292 authored Jan 17, 2023
2 parents ef157d7 + 7c5d89c commit 3299b7c
Show file tree
Hide file tree
Showing 12 changed files with 201 additions and 35 deletions.
13 changes: 8 additions & 5 deletions client/setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ universal = false

[flake8]
ignore =
E203, # space before : (needed for how black formats slicing)
# E266, # too many leading '#' for block comment
E501, # line too long
E731, # do not assign a lambda expression, use a def
W503, # line break before binary operator
# space before : (needed for how black formats slicing)
E203,
# line too long
E501,
# do not assign a lambda expression, use a def
E731,
# line break before binary operator
W503,
max-line-length = 88
# select = B,C,E,F,W,T4,B9
# max-complexity = 18
Expand Down
40 changes: 39 additions & 1 deletion client/src/lab_client/environment.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from datetime import datetime
import os
from typing import Optional, Literal
from typing import Optional, Literal, List

from contaxy.clients import AuthClient, FileClient, ExtensionClient
from contaxy.clients import DeploymentClient
Expand Down Expand Up @@ -301,6 +302,43 @@ def get_file_metadata(
"""
return self.file_handler.get_file_metadata(project, key, version)

def delete_remote_file(
self, key: str, version: Optional[str] = None, keep_latest_version: bool = False
) -> None:
"""Deletes a file based on the specified 'key'.
Args:
key (str): Key or url of the requested file.
version (Optional[str], optional): Version of the file to be deleted. Defaults to None.
keep_latest_version (bool, optional): _description_. Defaults to False.
"""
self.file_handler.delete_remote_file(key, version, keep_latest_version)

def delete_remote_files(
self, date_from: Optional[datetime] = None, date_to: Optional[datetime] = None
) -> None:
"""Deletes all files (models/datasets) of a project.
Args:
date_from (Optional[datetime], optional): The start date (in UTC format) from which the file has to be deleted. If none, all files will be deleted.
date_to (Optional[datetime], optional): The end date (in UTC format) until which the file has to be deleted. If none, all files will be deleted.
"""
self.file_handler.delete_remote_files(date_from, date_to)

def list_remote_files(
self, data_type: Literal['model', 'dataset'] = None, prefix: str = None
) -> List[File]:
"""Lists all the remote files.
Args:
data_type (Literal['model', 'dataset'], optional): The date type of the files to list. Defaults to None.
prefix (str, optional): The file name prefix. If 'None', all files would be listed.
Returns:
List[File]: List of the remote files.
"""
return self.file_handler.list_remote_files(data_type, prefix)

@property
def mlflow_handler(self) -> MLFlowHandler:
if self._mlflow_handler is None:
Expand Down
17 changes: 17 additions & 0 deletions client/src/lab_client/handler/file_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from lab_client.utils import file_handler_utils, request_utils
from zipfile import ZipFile
import shutil
from datetime import datetime

VALID_DATATYPES = ['dataset', 'model']

Expand Down Expand Up @@ -182,6 +183,21 @@ def delete_remote_file(
keep_latest_version=keep_latest_version,
)

def delete_remote_files(
self, date_from: Optional[datetime] = None, date_to: Optional[datetime] = None
) -> None:
"""
Delete a file from remote storage.
# Arguments
key: Key of the file.
keep_latest_version: If `True` the latest file version will be kept.
"""
self.file_client.delete_files(
project_id=self.env.project,
date_from=date_from,
date_to=date_to
)

def resolve_path_from_key(self, key: str, version: Optional[str] = None) -> str:
"""
Return the local path for a given key.
Expand Down Expand Up @@ -259,3 +275,4 @@ def get_file_metadata(
file_key, version)

return metadata_file

6 changes: 4 additions & 2 deletions client/src/lab_client/handler/job_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,13 @@ def delete_job(self, job_id: str) -> None:
job_id=job_id
)

def delete_jobs(self) -> None:
def delete_jobs(self, date_from: Optional[datetime] = None, date_to: Optional[datetime] = None) -> None:
"""Deletes all jobs of a project.
"""
self.deployment_client.delete_jobs(
project_id=self.env.project
project_id=self.env.project,
date_from=date_from,
date_to=date_to
)

def get_job_logs(
Expand Down
48 changes: 47 additions & 1 deletion client/tests/test_deployment_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from lab_client import Environment
from .conftest import test_settings
import pytest

from datetime import datetime, timedelta, timezone

@pytest.mark.integration
class TestJob:
Expand Down Expand Up @@ -51,6 +51,52 @@ def test_list_jobs_get_job_metadata(self) -> None:
job_list = env.job_handler.list_jobs()
assert len(job_list) == 0

def test_delete_jobs_within_time_period(self) -> None:
env = Environment(lab_endpoint=test_settings.LAB_BACKEND,
lab_api_token=test_settings.LAB_TOKEN,
project=test_settings.LAB_PROJECT)

input = JobInput(
container_image='ubuntu:latest',
display_name='Job2',
command=['/bin/bash', '-c', '--'],
args=['sleep 5']
)
job_id = env.job_handler.deploy_job(input)

status = env.job_handler.wait_for_job_completion(job_id)
assert status == True

date_from = datetime.now(timezone.utc)
date_to = datetime.now(timezone.utc) + timedelta(days=1)

env.job_handler.delete_jobs(date_from, date_to)
job_list = env.job_handler.list_jobs()
assert len(job_list) == 0

def test_delete_jobs_outside_time_period(self) -> None:
env = Environment(lab_endpoint=test_settings.LAB_BACKEND,
lab_api_token=test_settings.LAB_TOKEN,
project=test_settings.LAB_PROJECT)

input = JobInput(
container_image='ubuntu:latest',
display_name='Job2',
command=['/bin/bash', '-c', '--'],
args=['sleep 5']
)
job_id = env.job_handler.deploy_job(input)

status = env.job_handler.wait_for_job_completion(job_id)
assert status == True

date_from = datetime.now(timezone.utc) - timedelta(days=3)
date_to = datetime.now(timezone.utc) - timedelta(days=2)

env.job_handler.delete_jobs(date_from, date_to)
job_list = env.job_handler.list_jobs()
assert len(job_list) == 1

def test_job_logs(self) -> None:
env = Environment(lab_endpoint=test_settings.LAB_BACKEND,
lab_api_token=test_settings.LAB_TOKEN,
Expand Down
64 changes: 63 additions & 1 deletion client/tests/test_file_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from .conftest import test_settings
import requests
import pytest

from datetime import datetime, timedelta, timezone

@pytest.mark.integration
class TestFile:
Expand Down Expand Up @@ -184,3 +184,65 @@ def test_list_file_with_invalid_data_type(self) -> None:
env.upload_file(tf.name, "dataset")

env.file_handler.list_remote_files(data_type="datasets")

@pytest.mark.xfail(raises=Exception)
def test_delete_single_file(self) -> None:
env = Environment(lab_endpoint=test_settings.LAB_BACKEND,
lab_api_token=test_settings.LAB_TOKEN,
project=test_settings.LAB_PROJECT)

tf = tempfile.NamedTemporaryFile()
with open(tf.name, 'w') as f:
f.write("content 1")
f.close()
key = env.upload_file(tf.name, "dataset")

env.delete_remote_file(key)
# This should throw a 404 error as file will not be present.
env.get_file(key)

def test_delete_files_within_time_window(self) -> None:
env = Environment(lab_endpoint=test_settings.LAB_BACKEND,
lab_api_token=test_settings.LAB_TOKEN,
project=test_settings.LAB_PROJECT)

# Clear/Delete all files initially.
env.delete_remote_files()

# Test that files within the date window are deleted.
tf = tempfile.NamedTemporaryFile(prefix='abcd_')
with open(tf.name, 'w') as f:
f.write("content 1")
f.close()
env.upload_file(tf.name, "dataset")

date_from = datetime.now(timezone.utc)
date_to = datetime.now(timezone.utc) + timedelta(days=1)

env.delete_remote_files(date_from, date_to)

files = env.list_remote_files(data_type='dataset')
assert len(files) == 0

def test_delete_files_outside_time_window(self) -> None:
env = Environment(lab_endpoint=test_settings.LAB_BACKEND,
lab_api_token=test_settings.LAB_TOKEN,
project=test_settings.LAB_PROJECT)

# Clear/Delete all files initially.
env.delete_remote_files()

# Test that files outside the date window are not deleted.
tf = tempfile.NamedTemporaryFile(prefix='qwertz_')
with open(tf.name, 'w') as f:
f.write("content 1")
f.close()
env.upload_file(tf.name, "dataset")

date_from = datetime.now(timezone.utc) - timedelta(days=3)
date_to = datetime.now(timezone.utc) - timedelta(days=2)

env.delete_remote_files(date_from, date_to)

files = env.list_remote_files(data_type="dataset")
assert len(files) == 1
11 changes: 5 additions & 6 deletions components/lab-job-scheduler/backend/setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@ universal = false

[flake8]
ignore =
E203,
# space before : (needed for how black formats slicing)
# E266,
# too many leading '#' for block comment
E501,
E203,
# line too long
E731,
E501,
# do not assign a lambda expression, use a def
W503,
E731,
# line break before binary operator
W503,

max-line-length = 88
# select = B,C,E,F,W,T4,B9
# max-complexity = 18
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Optional

from contaxy.schema.deployment import JobInput
from pydantic import BaseModel, Field

Expand Down
11 changes: 5 additions & 6 deletions components/lab-mlflow-manager/backend/setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@ universal = false

[flake8]
ignore =
E203,
# space before : (needed for how black formats slicing)
# E266,
# too many leading '#' for block comment
E501,
E203,
# line too long
E731,
E501,
# do not assign a lambda expression, use a def
W503,
E731,
# line break before binary operator
W503,

max-line-length = 88
# select = B,C,E,F,W,T4,B9
# max-complexity = 18
Expand Down
11 changes: 5 additions & 6 deletions components/lab-workspace-manager/backend/setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@ universal = false

[flake8]
ignore =
E203,
# space before : (needed for how black formats slicing)
# E266,
# too many leading '#' for block comment
E501,
E203,
# line too long
E731,
E501,
# do not assign a lambda expression, use a def
W503,
E731,
# line break before binary operator
W503,

max-line-length = 88
# select = B,C,E,F,W,T4,B9
# max-complexity = 18
Expand Down
11 changes: 5 additions & 6 deletions components/template/backend/setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@ universal = false

[flake8]
ignore =
E203,
# space before : (needed for how black formats slicing)
# E266,
# too many leading '#' for block comment
E501,
E203,
# line too long
E731,
E501,
# do not assign a lambda expression, use a def
W503,
E731,
# line break before binary operator
W503,

max-line-length = 88
# select = B,C,E,F,W,T4,B9
# max-complexity = 18
Expand Down
2 changes: 1 addition & 1 deletion contaxy
Submodule contaxy updated 66 files
+2 −0 .github/actions/build-environment/Dockerfile
+0 −3 .github/actions/build-environment/extended-entrypoint.sh
+741 −772 backend/Pipfile.lock
+5 −5 backend/docs/contaxy.schema.shared.md
+1 −1 backend/openapi-spec.json
+1 −1 backend/src/contaxy/_about.py
+1 −16 backend/src/contaxy/api/endpoints/file.py
+10 −0 backend/src/contaxy/schema/shared.py
+1 −23 backend/tests/test_file_operations.py
+0 −4 build_requirements.txt
+3 −3 js-client/ApiClient.js
+2 −2 js-client/api/AuthApi.js
+2 −2 js-client/api/ExtensionsApi.js
+2 −2 js-client/api/FilesApi.js
+2 −2 js-client/api/JobsApi.js
+2 −2 js-client/api/JsonApi.js
+2 −2 js-client/api/ProjectsApi.js
+2 −2 js-client/api/ServicesApi.js
+2 −2 js-client/api/SystemApi.js
+2 −2 js-client/api/UsersApi.js
+2 −2 js-client/index.js
+1 −1 js-client/model/AccessLevel.js
+2 −2 js-client/model/AccessToken.js
+2 −2 js-client/model/AllowedImageInfo.js
+2 −2 js-client/model/ApiToken.js
+2 −2 js-client/model/AuthorizedAccess.js
+2 −2 js-client/model/BodyIntrospectToken.js
+2 −2 js-client/model/BodyLoginUserSession.js
+2 −2 js-client/model/BodyRegisterAdminUserSystemAdminPost.js
+2 −2 js-client/model/BodyRequestToken.js
+2 −2 js-client/model/BodyRevokeToken.js
+2 −2 js-client/model/BodyUploadFileProjectsProjectIdFilesFileKeyPost.js
+2 −2 js-client/model/Compute.js
+2 −2 js-client/model/DeploymentCompute.js
+1 −1 js-client/model/DeploymentStatus.js
+1 −1 js-client/model/DeploymentType.js
+11 −2 js-client/model/Extension.js
+2 −2 js-client/model/ExtensionInput.js
+1 −1 js-client/model/ExtensionType.js
+11 −2 js-client/model/File.js
+2 −2 js-client/model/FileInput.js
+11 −2 js-client/model/Job.js
+2 −2 js-client/model/JobInput.js
+2 −2 js-client/model/JsonDocument.js
+2 −2 js-client/model/OAuth2ErrorDetails.js
+2 −2 js-client/model/OAuthToken.js
+2 −2 js-client/model/OAuthTokenIntrospection.js
+2 −2 js-client/model/ProblemDetails.js
+11 −2 js-client/model/Project.js
+2 −2 js-client/model/ProjectCreation.js
+2 −2 js-client/model/ProjectInput.js
+2 −2 js-client/model/ResourceAction.js
+2 −2 js-client/model/ResourceActionExecution.js
+2 −2 js-client/model/ResponseListUsersInner.js
+11 −2 js-client/model/Service.js
+2 −2 js-client/model/ServiceInput.js
+2 −2 js-client/model/ServiceUpdate.js
+2 −2 js-client/model/SystemInfo.js
+1 −1 js-client/model/SystemState.js
+2 −2 js-client/model/SystemStatistics.js
+1 −1 js-client/model/TokenType.js
+2 −2 js-client/model/User.js
+2 −2 js-client/model/UserInput.js
+2 −2 js-client/model/UserPermission.js
+2 −2 js-client/model/UserRead.js
+2 −2 js-client/model/UserRegistration.js

0 comments on commit 3299b7c

Please sign in to comment.