Skip to content
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
6 changes: 3 additions & 3 deletions .github/workflows/build_docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ["3.11"]
python-version: ["3.12"]
os: [ubuntu-latest]

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7.0.0

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6.3.0
with:
python-version: ${{ matrix.python-version }}

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/linting.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7.0.0

- uses: actions/setup-python@v5
- uses: actions/setup-python@v6.3.0
with:
python-version: '3.11'
python-version: '3.12'
cache: 'pip'

- name: Installing dependencies
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/publish_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ jobs:
environment: production
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7.0.0

- uses: actions/setup-python@v5
- uses: actions/setup-python@v6.3.0
with:
python-version: "3.11"
python-version: "3.12"

- name: build
run: |
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,24 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ["3.11", "3.12"]
python-version: ["3.12"]
os: [ubuntu-latest, windows-latest, macos-15]
permissions:
contents: read
id-token: write

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7.0.0

- name: Azure Login
uses: Azure/login@v2
uses: Azure/login@v3.0.0
with:
client-id: f96c150d-cacf-4257-9cc9-54b2c68ec4ce
tenant-id: 3aa4a235-b6e2-48d5-9195-7fcf05b459b0
subscription-id: 87897772-fb27-495f-ae40-486a2df57baa

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6.3.0
with:
python-version: ${{ matrix.python-version }}

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ exclude = [".env", ".git", ".github", ".venv", "venv"]
line-length = 79

[tool.ruff.lint]
ignore = ["E501", "N802"]
ignore = ["E501", "N802", "TRY002", "BLE001"]

extend-select = [
"C4", # Flake8-comprehensions
Expand Down
2 changes: 1 addition & 1 deletion src/sumo/wrapper/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
except ImportError:
__version__ = "0.0.0"

__all__ = ["SumoClient", "RetryStrategy"]
__all__ = ["RetryStrategy", "SumoClient"]
60 changes: 10 additions & 50 deletions src/sumo/wrapper/_auth_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
import stat
import sys
import time
from datetime import datetime, timedelta, timezone
from datetime import UTC, datetime, timedelta
from pathlib import Path
from typing import Dict
from urllib.parse import parse_qs

import jwt
Expand Down Expand Up @@ -55,8 +54,6 @@ def __init__(self, resource_id):
self._login_timeout_minutes = 5
os.system("") # Ensure color init on all platforms (win10)

return

@tn.retry(
retry=tn.retry_if_exception(_maybe_nfs_exception),
stop=tn.stop_after_attempt(6),
Expand All @@ -77,7 +74,7 @@ def get_token(self):
# ELSE
return result["access_token"]

def get_authorization(self) -> Dict:
def get_authorization(self) -> dict:
token = self.get_token()
if token is None:
return {}
Expand All @@ -92,7 +89,6 @@ def store_shared_access_key_for_case(self, case_uuid, token):
) as f:
f.write(token)
protect_token_cache(self._resource_id, ".sharedkey", case_uuid)
return

def has_case_token(self, case_uuid):
return os.path.exists(
Expand All @@ -102,15 +98,11 @@ def has_case_token(self, case_uuid):
def delete_token(self):
return False

pass


class AuthProviderNone(AuthProvider):
def get_token(self):
raise Exception("No valid authorization provider found.")

pass


class AuthProviderSilent(AuthProvider):
def __init__(self, client_id, authority, resource_id):
Expand All @@ -130,16 +122,13 @@ def __init__(self, access_token):
payload = jwt.decode(access_token, options={"verify_signature": False})
self._expires = payload["exp"]
self._resource_id = payload["aud"]
return

def get_token(self):
if time.time() >= self._expires:
raise ValueError("Access token has expired.")
# ELSE
return self._access_token

pass


class AuthProviderRefreshToken(AuthProvider):
def __init__(self, refresh_token, client_id, authority, resource_id):
Expand All @@ -149,9 +138,6 @@ def __init__(self, refresh_token, client_id, authority, resource_id):
)
self._scope = scope_for_resource(resource_id)
self._app.acquire_token_by_refresh_token(refresh_token, [self._scope])
return

pass


@tn.retry(
Expand Down Expand Up @@ -186,14 +172,10 @@ def get_token_cache(resource_id, suffix):
token = FilePersistence(token_path).load()
with open(token_path, "w") as f:
f.truncate()
pass
encrypted_persistence.save(token)
pass
pass

persistence = build_encrypted_persistence(token_path)
cache = PersistedTokenCache(persistence)
pass
return cache


Expand All @@ -218,10 +200,7 @@ def protect_token_cache(resource_id, suffix, case_uuid=None):
foldermode = stat.filemode(os.stat(folder).st_mode)
if foldermode != "drwx------":
os.chmod(os.path.dirname(token_path), 0o700)
pass
pass
return
pass


class AuthProviderInteractive(AuthProvider):
Expand All @@ -237,8 +216,6 @@ def __init__(self, client_id, authority, resource_id):

if self.get_token() is None:
self.login()
pass
return

@tn.retry(
retry=tn.retry_if_exception(_maybe_nfs_exception),
Expand All @@ -262,7 +239,7 @@ def login(self):
+ "that is before "
+ str(
(
datetime.now()
datetime.now().astimezone()
+ timedelta(minutes=self._login_timeout_minutes)
).strftime("%H:%M:%S")
)
Expand Down Expand Up @@ -291,8 +268,6 @@ def login(self):
)
return

pass


class AuthProviderDeviceCode(AuthProvider):
def __init__(self, client_id, authority, resource_id):
Expand All @@ -305,8 +280,6 @@ def __init__(self, client_id, authority, resource_id):
self._scope = scope_for_resource(resource_id)
if self.get_token() is None:
self.login()
pass
return

@tn.retry(
retry=tn.retry_if_exception(_maybe_nfs_exception),
Expand All @@ -324,9 +297,10 @@ def login(self):
flow = self._app.initiate_device_flow(scopes)
if "error" in flow:
print(
"\n\n \033[31m"
+ "Failed to initiate device-code login. Err: %s\033[0m"
% json.dumps(flow, indent=4)
(
"\n\n \033[31m"
+ "Failed to initiate device-code login. Err: {}\033[0m"
).format(json.dumps(flow, indent=4))
)
return
flow["expires_at"] = (
Expand Down Expand Up @@ -363,15 +337,12 @@ def login(self):

return

pass


class AuthProviderManaged(AuthProvider):
def __init__(self, resource_id):
super().__init__(resource_id)
self._app = ManagedIdentityCredential()
self._scope = scope_for_resource(resource_id)
return

@tn.retry(
retry=tn.retry_if_exception(_maybe_nfs_exception),
Expand All @@ -386,8 +357,6 @@ def __init__(self, resource_id):
def get_token(self):
return self._app.get_token(self._scope).token

pass


class AuthProviderSumoToken(AuthProvider):
@tn.retry(
Expand All @@ -407,8 +376,6 @@ def __init__(self, resource_id, case_uuid=None):
with open(self.token_path, "r") as f:
self._token = f.readline().strip()

return

def get_token(self):
return self._token

Expand Down Expand Up @@ -460,7 +427,6 @@ def get_auth_provider(
token = auth_silent.get_token()
if token is not None:
return auth_silent
pass
# ELSE
if all(
os.getenv(x)
Expand All @@ -484,7 +450,6 @@ def get_auth_provider(
"\n\n\033[1mDetected chromium lockfile for different node; using firefox to authenticate.\033[0m"
)
os.environ["BROWSER"] = "firefox"
pass

return AuthProviderInteractive(client_id, authority, resource_id)
# ELSE
Expand All @@ -510,15 +475,10 @@ def cleanup_shared_keys():
token = file.read()
pq = parse_qs(token)
se = pq["se"][0]
end = datetime.strptime(se, "%Y-%m-%dT%H:%M:%S.%fZ")
now = datetime.now(timezone.utc)
end = datetime.fromisoformat(se)
now = datetime.now(UTC)
if now.timestamp() > end.timestamp():
os.unlink(ff)
pass
pass
pass
except Exception:
except Exception: # noqa: S110
pass
pass
pass
return
1 change: 0 additions & 1 deletion src/sumo/wrapper/_blob_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ def __init__(self, client, async_client, timeout, retry_strategy):
self._async_client = async_client
self._timeout = timeout
self._retry_strategy = retry_strategy
return

@raise_for_status
def upload_blob(self, blob: bytes, url: str):
Expand Down
11 changes: 3 additions & 8 deletions src/sumo/wrapper/_logging.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import logging
from datetime import datetime, timezone
from datetime import UTC, datetime


class LogHandlerSumo(logging.Handler):
def __init__(self, sumo_client):
logging.Handler.__init__(self)
self._sumoClient = sumo_client
return

def emit(self, record):
try:
dt = (
datetime.now(timezone.utc)
datetime.now(UTC)
.replace(microsecond=0, tzinfo=None)
.isoformat()
+ "Z"
Expand All @@ -32,10 +31,6 @@ def emit(self, record):
json["details"] = record.__dict__.get("details")

self._sumoClient.post("/message-log/new", json=json)
except Exception:
except Exception: # noqa: S110
# Never fail on logging
pass

return

pass
2 changes: 0 additions & 2 deletions src/sumo/wrapper/_retry_strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ def _log_retry_info(retry_state):
f"Attempts: {retry_state.attempt_number}; "
f"Elapsed: {retry_state.seconds_since_start}"
)
return


# Define the conditions for retrying based on exception types
Expand Down Expand Up @@ -49,7 +48,6 @@ def __init__(
self._multiplier = multiplier
self._exp_base = exp_base
self._before_sleep = before_sleep
return

def make_retryer(self) -> tn.Retrying:
return tn.Retrying(
Expand Down
Loading