Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add typing to sse.py #1338

Merged
merged 1 commit into from
Nov 22, 2023
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/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
os: [ubuntu-latest, windows-latest, macos-latest]

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Run spell check on Ubuntu
if: matrix.os == 'ubuntu-latest'
uses: codespell-project/actions-codespell@master
Expand All @@ -59,7 +59,7 @@ jobs:
echo "/Users/runner/.local/bin" >> $GITHUB_PATH
- name: Run unit tests
run: |
python setup.py install
pip install -e .
pytest
- name: Run functional tests on Ubuntu
if: matrix.os == 'ubuntu-latest'
Expand Down
3 changes: 2 additions & 1 deletion minio/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ def __init__(
)

def __del__(self):
self._http.clear()
if hasattr(self, "_http"): # Only required for unit test run
self._http.clear()

def _handle_redirect_response(
self, method, bucket_name, response, retry=False,
Expand Down
4 changes: 2 additions & 2 deletions minio/error.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ def __init__(self, code, content_type, body):
self._content_type = content_type
self._body = body
super().__init__(
f"non-XML response from server; "
f"Response code: {code}, Content-Type: {content_type}, Body: {body}"
f"non-XML response from server; Response code: {code}, "
f"Content-Type: {content_type}, Body: {body}"
)

def __reduce__(self):
Expand Down
4 changes: 2 additions & 2 deletions minio/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,11 @@ def _validate_sizes(object_size, part_size):
if part_size > 0:
if part_size < MIN_PART_SIZE:
raise ValueError(
f"part size {part_size} is not supported; minimum allowed 5MiB",
f"part size {part_size} is not supported; minimum allowed 5MiB"
)
if part_size > MAX_PART_SIZE:
raise ValueError(
f"part size {part_size} is not supported; maximum allowed 5GiB",
f"part size {part_size} is not supported; maximum allowed 5GiB"
)

if object_size >= 0:
Expand Down
3 changes: 2 additions & 1 deletion minio/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,8 @@ def _read(self):

if headers.get(":message-type") == "error":
raise MinioException(
f"{headers.get(':error-code')}: {headers.get(':error-message')}"
f"{headers.get(':error-code')}: "
f"{headers.get(':error-message')}"
)

if headers.get(":event-type") == "End":
Expand Down
21 changes: 11 additions & 10 deletions minio/sse.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,29 +27,30 @@
import base64
import json
from abc import ABCMeta, abstractmethod
from typing import Dict


class Sse:
"""Server-side encryption base class."""
__metaclass__ = ABCMeta

@abstractmethod
def headers(self):
def headers(self) -> Dict[str, str]:
"""Return headers."""

def tls_required(self): # pylint: disable=no-self-use
def tls_required(self) -> bool: # pylint: disable=no-self-use
"""Return TLS required to use this server-side encryption."""
return True

def copy_headers(self): # pylint: disable=no-self-use
def copy_headers(self) -> Dict[str, str]: # pylint: disable=no-self-use
"""Return copy headers."""
return {}


class SseCustomerKey(Sse):
""" Server-side encryption - customer key type."""

def __init__(self, key):
def __init__(self, key: bytes):
if len(key) != 32:
raise ValueError(
"SSE-C keys need to be 256 bit base64 encoded",
Expand All @@ -71,17 +72,17 @@ def __init__(self, key):
md5key,
}

def headers(self):
def headers(self) -> Dict[str, str]:
return self._headers.copy()

def copy_headers(self):
def copy_headers(self) -> Dict[str, str]:
return self._copy_headers.copy()


class SseKMS(Sse):
"""Server-side encryption - KMS type."""

def __init__(self, key, context):
def __init__(self, key: str, context: Dict):
self._headers = {
"X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": key,
"X-Amz-Server-Side-Encryption": "aws:kms"
Expand All @@ -92,17 +93,17 @@ def __init__(self, key, context):
base64.b64encode(data).decode()
)

def headers(self):
def headers(self) -> Dict[str, str]:
return self._headers.copy()


class SseS3(Sse):
"""Server-side encryption - S3 type."""

def headers(self):
def headers(self) -> Dict[str, str]:
return {
"X-Amz-Server-Side-Encryption": "AES256"
}

def tls_required(self):
def tls_required(self) -> bool:
return False
8 changes: 8 additions & 0 deletions minio/time.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
import time as ctime
from datetime import datetime, timezone

try:
from datetime import UTC
_UTC_IMPORTED = True
except ImportError:
_UTC_IMPORTED = False

_WEEK_DAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
_MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
"Nov", "Dec"]
Expand Down Expand Up @@ -102,6 +108,8 @@ def to_amz_date(value):

def utcnow():
"""Timezone-aware wrapper to datetime.utcnow()."""
if _UTC_IMPORTED:
return datetime.now(UTC).replace(tzinfo=timezone.utc)
return datetime.utcnow().replace(tzinfo=timezone.utc)


Expand Down
4 changes: 3 additions & 1 deletion tests/functional/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,9 @@ def _call_test(func, *args, **kwargs):
if log_entry.get("method"):
# pylint: disable=deprecated-method
args_string = ', '.join(getfullargspec(log_entry["method"]).args[1:])
log_entry["function"] = f"{log_entry['method'].__name__}({args_string})"
log_entry["function"] = (
f"{log_entry['method'].__name__}({args_string})"
)
log_entry["args"] = {
k: v for k, v in log_entry.get("args", {}).items() if v
}
Expand Down
5 changes: 4 additions & 1 deletion tests/unit/crypto_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ def test_correct(self):
plaintext = "Hello MinIO!"
encrypted = encrypt(plaintext.encode(), secret)
decrypted = decrypt(encrypted, secret).decode()
self.assertEquals(plaintext, decrypted)
if hasattr(self, "assertEquals"):
self.assertEquals(plaintext, decrypted)
else:
self.assertEqual(plaintext, decrypted)

def test_wrong(self):
secret = "topsecret"
Expand Down
3 changes: 3 additions & 0 deletions tests/unit/minio_mocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ class MockConnection(object):
def __init__(self):
self.requests = []

def clear(self):
pass

def mock_add_request(self, request):
self.requests.append(request)

Expand Down
3 changes: 2 additions & 1 deletion tests/unit/retention_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@
from minio import xml
from minio.commonconfig import COMPLIANCE, GOVERNANCE
from minio.retention import Retention
from minio.time import utcnow


class RetentionTest(TestCase):
def test_config(self):
config = Retention(GOVERNANCE, datetime.utcnow() + timedelta(days=10))
config = Retention(GOVERNANCE, utcnow() + timedelta(days=10))
xml.marshal(config)

config = xml.unmarshal(
Expand Down