Source code for aio_aws.utils

# Copyright 2019-2021 Darren Weber
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from datetime import datetime
from datetime import timezone
from email.utils import format_datetime
from email.utils import formatdate
from email.utils import parsedate_to_datetime
from math import floor
from typing import Optional

from botocore.exceptions import ClientError

from aio_aws.logger import get_logger

LOGGER = get_logger(__name__)


[docs]def handle_head_error_code(error: ClientError, item: str = None) -> Optional[bool]: err_code = error.response.get("Error", {}).get("Code") if err_code == "401": LOGGER.debug("GET HEAD 401: invalid credentials: %s", item) return False if err_code == "403": LOGGER.debug("GET HEAD 403: permission denied: %s", item) return False if err_code == "404": LOGGER.debug("GET HEAD 404: object missing: %s", item) return False return None
[docs]def response_code(response) -> int: return int(response.get("ResponseMetadata", {}).get("HTTPStatusCode"))
[docs]def response_success(response) -> bool: code = response_code(response) if code: return 200 <= code < 300 else: return False
[docs]def utc_now() -> datetime: """UTC datetime - tz aware""" return datetime.utcnow().replace(tzinfo=timezone.utc)
[docs]def utc_timestamp() -> float: """Unix timestamp - time since the epoch in seconds""" return utc_now().timestamp()
[docs]def utc_unix_milliseconds() -> int: """Unix timestamp - time since the epoch in milliseconds""" return floor(utc_timestamp() * 1e3)
[docs]def datetime_to_unix_milliseconds(dt: datetime) -> int: """datetime to unix timestamp - time since the epoch in milliseconds""" utc_dt = dt.astimezone(timezone.utc) return floor(utc_dt.timestamp() * 1e3)
[docs]def http_date_to_datetime(http_date: str) -> datetime: """ Parse a HTTP date string into a datetime. :param http_date: e.g. "Mon, 23 Mar 2020 15:29:33 GMT" :return: a datetime """ return parsedate_to_datetime(http_date)
[docs]def http_date_to_timestamp(http_date: str) -> float: """ Parse a HTTP date string into a timestamp as seconds since the epoch. :param http_date: e.g. "Mon, 23 Mar 2020 15:29:33 GMT" :return: a timestamp (seconds since the epoch) """ return parsedate_to_datetime(http_date).timestamp()
[docs]def datetime_to_http_date(dt: datetime) -> str: """ Parse a datetime into an HTTP date string (using GMT). :param dt: a datetime :return: an HTTP date string, e.g. "Mon, 23 Mar 2020 15:29:33 GMT" """ return format_datetime(dt, usegmt=True)
[docs]def timestamp_to_http_date(ts: float) -> str: """ Parse a timestamp (seconds since the epoch) into an HTTP date string (using GMT). :param ts: a timestamp (seconds since the epoch) :return: an HTTP date string, e.g. "Mon, 23 Mar 2020 15:29:33 GMT" """ return formatdate(ts, usegmt=True)
[docs]def datetime_from_unix_milliseconds(msec: float) -> datetime: return datetime.utcfromtimestamp(msec / 1e3).replace(tzinfo=timezone.utc)