Skip to content
4 changes: 3 additions & 1 deletion cs3client/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
"""

import logging
from typing import Optional

import cs3.app.registry.v1beta1.registry_api_pb2 as cs3arreg
import cs3.app.registry.v1beta1.resources_pb2 as cs3arres
import cs3.gateway.v1beta1.gateway_api_pb2 as cs3gw
Expand Down Expand Up @@ -44,7 +46,7 @@ def __init__(
self._config: Config = config

def open_in_app(
self, auth_token: tuple, resource: Resource, view_mode: str = None, app: str = None
self, auth_token: tuple, resource: Resource, view_mode: Optional[str] = None, app: Optional[str] = None
) -> cs3apr.OpenInAppURL:
"""
Open a file in an app, given the resource, view mode (VIEW_MODE_VIEW_ONLY, VIEW_MODE_READ_ONLY,
Expand Down
2 changes: 1 addition & 1 deletion cs3client/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from cs3.rpc.v1beta1.code_pb2 import CODE_OK

from .cs3client import CS3Client
from .exceptions.exceptions import AuthenticationException, SecretNotSetException
from .exceptions import AuthenticationException, SecretNotSetException
from .config import Config


Expand Down
5 changes: 3 additions & 2 deletions cs3client/checkpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
Last updated: 30/08/2024
"""

from typing import Generator
from typing import Generator, Optional
import logging

import cs3.storage.provider.v1beta1.resources_pb2 as cs3spr
import cs3.storage.provider.v1beta1.provider_api_pb2 as cs3spp
from cs3.gateway.v1beta1.gateway_api_pb2_grpc import GatewayAPIStub
Expand Down Expand Up @@ -65,7 +66,7 @@ def list_file_versions(
return res.versions

def restore_file_version(
self, auth_token: tuple, resource: Resource, version_key: str, lock_id: str = None
self, auth_token: tuple, resource: Resource, version_key: str, lock_id: Optional[str] = None
) -> None:
"""
Restore a file to a previous version.
Expand Down
84 changes: 84 additions & 0 deletions cs3client/exceptions/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"""
exceptions

Custom exception classes for the CS3 client.
Where applicable, the default values correspond to the Linux standard error strings.

Authors: Rasmus Welander, Diogo Castro, Giuseppe Lo Presti.
Emails: [email protected], [email protected], [email protected]
Last updated: 01/08/2024
"""


class AuthenticationException(Exception):
"""
Standard error thrown when attempting an operation without the required access rights
"""

def __init__(self, message: str = "Operation not permitted"):
super().__init__(message)


class PermissionDeniedException(IOError):
"""
Standard permission denied message
"""

def __init__(self, message: str = "Permission denied"):
super().__init__(message)


class NotFoundException(IOError):
"""
Standard file missing message
"""

def __init__(self, message: str = "No such file or directory"):
super().__init__(message)


class SecretNotSetException(Exception):
"""
Standard file missing message
"""

def __init__(self, message: str = "Secret was not set, unable to authenticate"):
super().__init__(message)


class FileLockedException(IOError):
"""
Standard error thrown when attempting to overwrite a file/xattr with a mistmatched lock,
or when a lock operation cannot be performed because of failed preconditions
"""

def __init__(self, message: str = "Lock mismatch"):
super().__init__(message)


class AlreadyExistsException(IOError):
"""
Standard error thrown when attempting to create a resource that already exists
"""

def __init__(self, message: str = "File exists"):
super().__init__(message)


class UnimplementedException(Exception):
"""
Standard error thrown when attempting to use a feature that is not implemented
"""

def __init__(self, message: str = "Not implemented"):
super().__init__(message)


class UnknownException(Exception):
"""
Standard exception to be thrown when we get an error that is unknown, e.g. not defined in the cs3api
"""

def __init__(self, message: str = ""):
super().__init__(message)

73 changes: 0 additions & 73 deletions cs3client/exceptions/exceptions.py

This file was deleted.

26 changes: 13 additions & 13 deletions cs3client/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
import logging
import http
import requests
from typing import Union
from typing import Generator
from typing import Union, Optional, Generator
import cs3.storage.provider.v1beta1.resources_pb2 as cs3spr
import cs3.storage.provider.v1beta1.provider_api_pb2 as cs3sp
from cs3.gateway.v1beta1.gateway_api_pb2_grpc import GatewayAPIStub
Expand All @@ -20,7 +19,7 @@


from .config import Config
from .exceptions.exceptions import AuthenticationException, FileLockedException
from .exceptions import AuthenticationException, FileLockedException
from .cs3resource import Resource
from .statuscodehandler import StatusCodeHandler

Expand Down Expand Up @@ -71,7 +70,7 @@ def stat(self, auth_token: tuple, resource: Resource) -> cs3spr.ResourceInfo:
)
return res.info

def set_xattr(self, auth_token: tuple, resource: Resource, key: str, value: str, lock_id: str = None) -> None:
def set_xattr(self, auth_token: tuple, resource: Resource, key: str, value: str, lock_id: Optional[str] = None) -> None:
"""
Set the extended attribute <key> to <value> for a resource.

Expand All @@ -94,7 +93,7 @@ def set_xattr(self, auth_token: tuple, resource: Resource, key: str, value: str,
self._status_code_handler.handle_errors(res.status, "set extended attribute", resource.get_file_ref_str())
self._log.debug(f'msg="Invoked setxattr" trace="{res.status.trace}"')

def remove_xattr(self, auth_token: tuple, resource: Resource, key: str, lock_id: str = None) -> None:
def remove_xattr(self, auth_token: tuple, resource: Resource, key: str, lock_id: Optional[str] = None) -> None:
"""
Remove the extended attribute <key>.

Expand All @@ -113,7 +112,7 @@ def remove_xattr(self, auth_token: tuple, resource: Resource, key: str, lock_id:
self._log.debug(f'msg="Invoked UnsetArbitraryMetaData" trace="{res.status.trace}"')

def rename_file(
self, auth_token: tuple, resource: Resource, newresource: Resource, lock_id: str = None
self, auth_token: tuple, resource: Resource, newresource: Resource, lock_id: Optional[str] = None
) -> None:
"""
Rename/move resource to new resource.
Expand All @@ -133,7 +132,7 @@ def rename_file(
self._status_code_handler.handle_errors(res.status, "rename file", resource.get_file_ref_str())
self._log.debug(f'msg="Invoked Move" trace="{res.status.trace}"')

def remove_file(self, auth_token: tuple, resource: Resource, lock_id: str = None) -> None:
def remove_file(self, auth_token: tuple, resource: Resource, lock_id: Optional[str] = None) -> None:
"""
Remove a resource.

Expand Down Expand Up @@ -171,7 +170,8 @@ def touch_file(self, auth_token: tuple, resource: Resource) -> None:

def write_file(
self, auth_token: tuple, resource: Resource, content: Union[str, bytes], size: int,
lock_md: tuple = ('', ''), disable_versioning: bool = False
app_name: Optional[str] = None, lock_id: Optional[str] = None,
disable_versioning: Optional[bool] = False
) -> None:
"""
Write a file using the given userid as access token. The entire content is written
Expand All @@ -183,15 +183,15 @@ def write_file(
:param resource: Resource to write content to
:param content: content to write
:param size: size of content (optional)
:param lock_md: tuple (<app_name>, <lock_id>)
:param disable_versioning: bool to disable versioning on EOS
:param app_name: application name (optional)
:param lock_id: lock id (optional)
:param disable_versioning: bool to disable versioning on EOS (optional)
:return: None (Success)
:raises: FileLockedException (File is locked),
:raises: AuthenticationException (Authentication failed)
:raises: UnknownException (Unknown error)

"""
app_name, lock_id = lock_md
tstart = time.time()
# prepare endpoint
if size == -1:
Expand Down Expand Up @@ -229,7 +229,7 @@ def write_file(
"X-Reva-Transfer": protocol.token,
**dict([auth_token]),
"X-Lock-Id": lock_id,
"X-Lock_Holder": app_name,
"X-Lock-Holder": app_name,
}
if disable_versioning:
headers.update({"X-Disable-Versioning": "true"})
Expand Down Expand Up @@ -273,7 +273,7 @@ def write_file(
f'elapsedTimems="{(tend - tstart) * 1000:.1f}"'
)

def read_file(self, auth_token: tuple, resource: Resource, lock_id: str = None) -> Generator[bytes, None, None]:
def read_file(self, auth_token: tuple, resource: Resource, lock_id: Optional[str] = None) -> Generator[bytes, None, None]:
"""
Read a file. Note that the function is a generator, managed by the app server.

Expand Down
Loading
Loading