Skip to content

Commit 70a2f42

Browse files
author
Rasmus Oscar Welander
committed
[CI] use Python 3.9 as that is what we have in Alma9
1 parent 14d141b commit 70a2f42

File tree

5 files changed

+62
-46
lines changed

5 files changed

+62
-46
lines changed

.github/workflows/ci-tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ jobs:
1515
- name: Checkout
1616
uses: actions/checkout@v4
1717

18-
- name: Set up Python 3.12
18+
- name: Set up Python 3.9
1919
uses: actions/setup-python@v3
2020
with:
21-
python-version: "3.12"
21+
python-version: "3.9"
2222

2323
- name: Install dependencies
2424
run: |

cs3client/auth.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import jwt
1111
import datetime
1212
import logging
13+
from typing import Union
1314
from cs3.gateway.v1beta1.gateway_api_pb2 import AuthenticateRequest
1415
from cs3.auth.registry.v1beta1.registry_api_pb2 import ListAuthProvidersRequest
1516
from cs3.gateway.v1beta1.gateway_api_pb2_grpc import GatewayAPIStub
@@ -38,9 +39,9 @@ def __init__(self, cs3_client: CS3Client) -> None:
3839
self._log: logging.Logger = cs3_client._log
3940
self._config: Config = cs3_client._config
4041
# The user should be able to change the client secret (e.g. token) and client id at runtime
41-
self._client_secret: str | None = self._config.auth_client_secret
42-
self._client_id: str | None = self._config.auth_client_id
43-
self._token: str | None = None
42+
self._client_secret: Union[str, None] = self._config.auth_client_secret
43+
self._client_id: Union[str, None] = self._config.auth_client_id
44+
self._token: Union[str, None] = None
4445

4546
def set_client_secret(self, token: str) -> None:
4647
"""

cs3client/cs3resource.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"""
88

99
import cs3.storage.provider.v1beta1.resources_pb2 as cs3spr
10+
from typing import Union
1011

1112

1213
class Resource:
@@ -26,12 +27,12 @@ class Resource:
2627

2728
def __init__(
2829
self,
29-
abs_path: str | None = None,
30-
rel_path: str | None = None,
31-
opaque_id: str | None = None,
32-
parent_id: str | None = None,
33-
storage_id: str | None = None,
34-
space_id: str | None = None,
30+
abs_path: Union[str, None] = None,
31+
rel_path: Union[str, None] = None,
32+
opaque_id: Union[str, None] = None,
33+
parent_id: Union[str, None] = None,
34+
storage_id: Union[str, None] = None,
35+
space_id: Union[str, None] = None,
3536
) -> None:
3637
"""
3738
initializes the Resource class, either abs_path, rel_path or opaque_id is required
@@ -45,15 +46,15 @@ def __init__(
4546
:param storage_id: storage id (optional)
4647
:param space_id: space id (optional)
4748
"""
48-
self._abs_path: str | None = abs_path
49-
self._rel_path: str | None = rel_path
50-
self._parent_id: str | None = parent_id
51-
self._opaque_id: str | None = opaque_id
52-
self._space_id: str | None = space_id
53-
self._storage_id: str | None = storage_id
49+
self._abs_path: Union[str, None] = abs_path
50+
self._rel_path: Union[str, None] = rel_path
51+
self._parent_id: Union[str, None] = parent_id
52+
self._opaque_id: Union[str, None] = opaque_id
53+
self._space_id: Union[str, None] = space_id
54+
self._storage_id: Union[str, None] = storage_id
5455

5556
@classmethod
56-
def from_file_ref_and_endpoint(cls, file: str, endpoint: str | None = None) -> "Resource":
57+
def from_file_ref_and_endpoint(cls, file: str, endpoint: Union[str, None] = None) -> "Resource":
5758
"""
5859
Extracts the attributes from the file and endpoint and returns a resource.
5960

cs3client/file.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import logging
1111
import http
1212
import requests
13+
from typing import Union
1314
from typing import Generator
1415
import cs3.storage.provider.v1beta1.resources_pb2 as cs3spr
1516
import cs3.storage.provider.v1beta1.provider_api_pb2 as cs3sp
@@ -169,7 +170,7 @@ def touch_file(self, auth_token: tuple, resource: Resource) -> None:
169170
self._log.debug(f'msg="Invoked TouchFile" trace="{res.status.trace}"')
170171

171172
def write_file(
172-
self, auth_token: tuple, resource: Resource, content: str | bytes, size: int, lock_md: tuple = None
173+
self, auth_token: tuple, resource: Resource, content: Union[str, bytes], size: int, lock_md: tuple = None
173174
) -> None:
174175
"""
175176
Write a file using the given userid as access token. The entire content is written
@@ -310,9 +311,11 @@ def read_file(self, auth_token: tuple, resource: Resource, lock_id: str = None)
310311
raise IOError(e)
311312
data = fileget.iter_content(self._config.chunk_size)
312313
if fileget.status_code != http.client.OK:
314+
# status.message.replace('"', "'") is not allowed inside f strings python<3.12
315+
status_msg = fileget.reason.replace('"', "'")
313316
self._log.error(
314317
f'msg="Error downloading file from Reva" code="{fileget.status_code}" '
315-
f'reason="{fileget.reason.replace('"', "'")}"'
318+
f'reason="{status_msg}"'
316319
)
317320
raise IOError(fileget.reason)
318321
else:
@@ -358,7 +361,7 @@ def list_dir(
358361
for info in res.infos:
359362
yield info
360363

361-
def _set_lock_using_xattr(self, auth_token, resource: Resource, app_name: str, lock_id: int | str) -> None:
364+
def _set_lock_using_xattr(self, auth_token, resource: Resource, app_name: str, lock_id: Union[int, str]) -> None:
362365
""""
363366
Set a lock to a resource with the given value metadata and appname as holder
364367
@@ -379,7 +382,7 @@ def _set_lock_using_xattr(self, auth_token, resource: Resource, app_name: str, l
379382
self.set_xattr(resource, LOCK_ATTR_KEY, f"{app_name}!{lock_id}!{expiration}", None)
380383
return
381384

382-
def set_lock(self, auth_token: tuple, resource: Resource, app_name: str, lock_id: int | str) -> None:
385+
def set_lock(self, auth_token: tuple, resource: Resource, app_name: str, lock_id: Union[int, str]) -> None:
383386
"""
384387
Set a lock to a resource with the given value and appname as holder
385388
@@ -441,7 +444,7 @@ def _get_lock_using_xattr(self, auth_token: tuple, resource: Resource) -> dict:
441444
except KeyError:
442445
return None
443446

444-
def get_lock(self, auth_token: tuple, resource: Resource) -> cs3spr.Lock | dict | None:
447+
def get_lock(self, auth_token: tuple, resource: Resource) -> Union[cs3spr.Lock, dict, None]:
445448
"""
446449
Get the lock for the given filepath
447450
@@ -482,7 +485,8 @@ def get_lock(self, auth_token: tuple, resource: Resource) -> cs3spr.Lock | dict
482485
}
483486

484487
def _refresh_lock_using_xattr(
485-
self, auth_token: tuple, resource: Resource, app_name: str, lock_id: str | int, existing_lock_id: str | int = None
488+
self, auth_token: tuple, resource: Resource, app_name: str, lock_id: Union[str, int],
489+
existing_lock_id: Union[str, int] = None
486490
) -> None:
487491
"""
488492
Refresh the lock metadata for the given filepath
@@ -515,8 +519,8 @@ def _refresh_lock_using_xattr(
515519
return
516520

517521
def refresh_lock(
518-
self, auth_token: tuple, resource: Resource, app_name: str, lock_id: str | int,
519-
existing_lock_id: str | int = None
522+
self, auth_token: tuple, resource: Resource, app_name: str, lock_id: Union[str, int],
523+
existing_lock_id: Union[str, int] = None
520524
):
521525
"""
522526
Refresh the lock for the given filepath
@@ -555,7 +559,9 @@ def refresh_lock(
555559
self._log.debug(f'msg="Invoked RefreshLock" {resource.get_file_ref_str()} result="{res.status.trace}" '
556560
f'value="{lock_id}" old_value="{existing_lock_id}"')
557561

558-
def _unlock_using_xattr(self, auth_token: tuple, resource: Resource, app_name: str, lock_id: str | int) -> None:
562+
def _unlock_using_xattr(
563+
self, auth_token: tuple, resource: Resource, app_name: str, lock_id: Union[str, int]
564+
) -> None:
559565
"""
560566
Remove the lock for the given filepath
561567
@@ -583,7 +589,7 @@ def _unlock_using_xattr(self, auth_token: tuple, resource: Resource, app_name: s
583589
self.remove_xattr(resource, LOCK_ATTR_KEY, None)
584590
return
585591

586-
def unlock(self, auth_token: tuple, resource: Resource, app_name, lock_id: str | int):
592+
def unlock(self, auth_token: tuple, resource: Resource, app_name, lock_id: Union[str, int]):
587593
"""
588594
Remove the lock for the given filepath
589595

cs3client/statuscodehandler.py

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,78 +20,86 @@ def __init__(self, log: logging.Logger, config: Config) -> None:
2020
self._log = log
2121
self._config = config
2222

23-
def _log_not_found_info(self, status: cs3status.Status, operation: str, msg: str = None) -> None:
23+
def _log_not_found_info(self, status: cs3status.Status, operation: str, status_msg: str, msg: str = None) -> None:
2424
self._log.info(
2525
f'msg="Not found on {operation}" {msg + " " if msg else ""} '
2626
f'userid="{self._config.auth_client_id if self._config.auth_client_id else "no_id_set"}" '
27-
f'trace="{status.trace}" reason="{status.message.replace('"', "'")}"'
27+
f'trace="{status.trace}" reason="{status_msg}"'
2828
)
2929

30-
def _log_authentication_error(self, status: cs3status.Status, operation: str, msg: str = None) -> None:
30+
def _log_authentication_error(
31+
self, status: cs3status.Status, operation: str, status_msg: str, msg: str = None
32+
) -> None:
3133
self._log.error(
3234
f'msg="Authentication failed on {operation}" {msg + " " if msg else ""}'
3335
f'userid="{self._config.auth_client_id if self._config.auth_client_id else "no_id_set"}" '
34-
f'trace="{status.trace}" reason="{status.message.replace('"', "'")}"'
36+
f'trace="{status.trace}" reason="{status_msg}"'
3537
)
3638

37-
def _log_unknown_error(self, status: cs3status.Status, operation: str, msg: str = None) -> None:
39+
def _log_unknown_error(self, status: cs3status.Status, operation: str, status_msg: str, msg: str = None) -> None:
3840
self._log.error(
3941
f'msg="Failed to {operation}, unknown error" {msg + " " if msg else ""}'
4042
f'userid="{self._config.auth_client_id if self._config.auth_client_id else "no_id_set"}" '
41-
f'trace="{status.trace}" reason="{status.message.replace('"', "'")}"'
43+
f'trace="{status.trace}" reason="{status_msg}"'
4244
)
4345

44-
def _log_precondition_info(self, status: cs3status.Status, operation: str, msg: str = None) -> None:
46+
def _log_precondition_info(
47+
self, status: cs3status.Status, operation: str, status_msg: str, msg: str = None
48+
) -> None:
4549
self._log.info(
4650
f'msg="Failed precondition on {operation}" {msg + " " if msg else ""}'
4751
f'userid="{self._config.auth_client_id if self._config.auth_client_id else "no_id_set"}" '
48-
f'trace="{status.trace}" reason="{status.message.replace('"', "'")}"'
52+
f'trace="{status.trace}" reason="{status_msg}"'
4953
)
5054

51-
def _log_already_exists(self, status: cs3status.Status, operation: str, msg: str = None) -> None:
55+
def _log_already_exists(self, status: cs3status.Status, operation: str, status_msg: str, msg: str = None) -> None:
5256
self._log.info(
5357
f'msg="Already exists on {operation}" {msg + " " if msg else ""}'
5458
f'userid="{self._config.auth_client_id if self._config.auth_client_id else "no_id_set"}" '
55-
f'trace="{status.trace}" reason="{status.message.replace('"', "'")}"'
59+
f'trace="{status.trace}" reason="{status_msg}"'
5660
)
5761

58-
def _log_unimplemented(self, status: cs3status.Status, operation: str, msg: str = None) -> None:
62+
def _log_unimplemented(self, status: cs3status.Status, operation: str, status_msg: str, msg: str = None) -> None:
5963
self._log.info(
6064
f'msg="Invoked {operation} on unimplemented feature" {msg + " " if msg else ""}'
6165
f'userid="{self._config.auth_client_id if self._config.auth_client_id else "no_id_set"}" '
62-
f'trace="{status.trace}" reason="{status.message.replace('"', "'")}"'
66+
f'trace="{status.trace}" reason="{status_msg}"'
6367
)
6468

6569
def handle_errors(self, status: cs3status.Status, operation: str, msg: str = None) -> None:
70+
6671
if status.code == cs3code.CODE_OK:
6772
return
73+
# status.message.replace('"', "'") is not allowed inside f strings python<3.12
74+
status_message = status.message.replace('"', "'")
75+
6876
if status.code == cs3code.CODE_FAILED_PRECONDITION or status.code == cs3code.CODE_ABORTED:
69-
self._log_precondition_info(status, operation, msg)
77+
self._log_precondition_info(status, operation, status_message, msg)
7078
raise FileLockedException(f'Failed precondition: operation="{operation}" '
7179
f'status_code="{status.code}" message="{status.message}"')
7280
if status.code == cs3code.CODE_ALREADY_EXISTS:
73-
self._log_already_exists(status, operation, msg)
81+
self._log_already_exists(status, operation, status_message, msg)
7482
raise AlreadyExistsException(f'Resource already exists: operation="{operation}" '
7583
f'status_code="{status.code}" message="{status.message}"')
7684
if status.code == cs3code.CODE_UNIMPLEMENTED:
7785
self._log.info(f'msg="Invoked {operation} on unimplemented feature" ')
7886
raise UnimplementedException(f'Unimplemented feature: operation="{operation}" '
7987
f'status_code="{status.code}" message="{status.message}"')
8088
if status.code == cs3code.CODE_NOT_FOUND:
81-
self._log_not_found_info(status, operation, msg)
89+
self._log_not_found_info(status, operation, status_message, msg)
8290
raise NotFoundException(f'Not found: operation="{operation}" '
8391
f'status_code="{status.code}" message="{status.message}"')
8492
if status.code == cs3code.CODE_UNAUTHENTICATED:
85-
self._log_authentication_error(status, operation, msg)
93+
self._log_authentication_error(status, operation, status_message, msg)
8694
raise AuthenticationException(f'Operation not permitted: operation="{operation}" '
8795
f'status_code="{status.code}" message="{status.message}"')
8896
if status.code != cs3code.CODE_OK:
8997
if "path not found" in str(status.message).lower():
9098
self._log.info(f'msg="Invoked {operation} on missing file" ')
9199
raise NotFoundException(
92100
message=f'No such file or directory: operation="{operation}" '
93-
f'status_code="{status.code}" message="{status.message}"'
101+
f'status_code="{status.code}" message="{status.message}"'
94102
)
95-
self._log_unknown_error(status, operation, msg)
103+
self._log_unknown_error(status, operation, status_message, msg)
96104
raise UnknownException(f'Unknown Error: operation="{operation}" status_code="{status.code}" '
97105
f'message="{status.message}"')

0 commit comments

Comments
 (0)