diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c6e6625..952c188 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -18,8 +18,8 @@ jobs: python: [ "3.8", "3.9", "3.10", "3.11" ] requests: [ "2.26", "2.27", "2.28", "2.29" ] steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} architecture: x64 @@ -30,16 +30,17 @@ jobs: - run: poetry add requests@~${{ matrix.requests }} - run: cp .github-ci.env .env - run: poetry run pytest - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: - name: coverage-report + name: coverage-report-python-${{ matrix.python }}-requests-${{ matrix.requests }} path: ./coverage.xml + overwrite: true pre-commit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: "3.10" - uses: pre-commit/action@v3.0.0 @@ -50,15 +51,15 @@ jobs: needs: pytest runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: 3.9 architecture: x64 - run: pip install --upgrade pip - run: pip install poetry - run: poetry build - - uses: pypa/gh-action-pypi-publish@master + - uses: pypa/gh-action-pypi-publish@release/v1 with: password: ${{ secrets.pypi_password }} @@ -67,8 +68,12 @@ jobs: - pytest runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/download-artifact@v2 + - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 with: - name: coverage-report - - uses: codecov/codecov-action@v1 + pattern: coverage-report-* + path: coverage-reports + - uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + directory: coverage-reports diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml index 08e15a6..61ba4fb 100644 --- a/.github/workflows/semgrep.yml +++ b/.github/workflows/semgrep.yml @@ -12,11 +12,11 @@ name: Semgrep jobs: semgrep: name: Scan - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest env: SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} container: image: returntocorp/semgrep steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: semgrep ci diff --git a/README.md b/README.md index 6b0336d..d4b8b8e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # · xcover-python · + [![Supported Versions](https://img.shields.io/pypi/pyversions/xcover-python.svg)](https://pypi.org/project/xcover-python) [![codecov](https://codecov.io/gh/CoverGenius/xcover-python/branch/master/graph/badge.svg?token=KINNTVZV07)](https://codecov.io/gh/CoverGenius/xcover-python) @@ -16,7 +17,7 @@ or - poertry install xcover-python + poetry install xcover-python ## Features @@ -50,15 +51,17 @@ Alternatively, it is possible to use env variables. The full list of configuration options: -* `XC_BASE_URL` (`XCoverConfig.base_url`): XCover base URL (e.g. `https://api.xcover.com/api/v2/`). -* `XC_PARTNER_CODE` (`XCoverConfig.partner_code`): Partner code (e.g. `LLODT`). -* `XC_HTTP_TIMEOUT` (`XCoverConfig.http_timeout`): HTTP timeout in seconds. Default value is `10`. -* `XC_AUTH_API_KEY` (`XCoverConfig.auth_api_key`): API key to use. -* `XC_AUTH_API_SECRET` (`XCoverConfig.auth_api_secret`): API secret to use. -* `XC_AUTH_ALGORITHM` (`XCoverConfig.auth_algorithm`): HMAC encoding algorithm to use. Default is `hmac-sha512`. -* `XC_AUTH_HEADERS` (`XCoverConfig.auth_headers`): Headers to sign. Default is `(request-target) date`. -* `XC_RETRY_TOTAL` (`XCoverConfig.retry_total`): Total number of retries. Default is `5`. -* `XC_RETRY_BACKOFF_FACTOR` (`XCoverConfig.retry_backoff_factor`): Backoff factor for retries timeout. Default is `2`. +| Environment Variable | Config Property | Description | Default Value | +|---------------------|-----------------|-------------|---------------| +| `XC_BASE_URL` | `XCoverConfig.base_url` | XCover base URL (e.g. `https://api.xcover.com/api/v2/`) | - | +| `XC_PARTNER_CODE` | `XCoverConfig.partner_code` | Partner code (e.g. `LLODT`) | - | +| `XC_HTTP_TIMEOUT` | `XCoverConfig.http_timeout` | HTTP timeout in seconds | `10` | +| `XC_AUTH_API_KEY` | `XCoverConfig.auth_api_key` | API key to use | - | +| `XC_AUTH_API_SECRET` | `XCoverConfig.auth_api_secret` | API secret to use | - | +| `XC_AUTH_ALGORITHM` | `XCoverConfig.auth_algorithm` | HMAC encoding algorithm to use | `hmac-sha512` | +| `XC_AUTH_HEADERS` | `XCoverConfig.auth_headers` | Headers to sign | `(request-target) date` | +| `XC_RETRY_TOTAL` | `XCoverConfig.retry_total` | Total number of retries | `5` | +| `XC_RETRY_BACKOFF_FACTOR` | `XCoverConfig.retry_backoff_factor` | Backoff factor for retries timeout | `2` | ## Usage example diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..a19e83c --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,17 @@ +from datetime import datetime, timezone +from unittest import mock + +from xcover.utils import http_date + + +def test_http_date(): + fixed_dt = datetime(2025, 4, 8, 12, 0, 0, tzinfo=timezone.utc) + + with mock.patch("xcover.utils.datetime") as mock_datetime: + mock_datetime.now.return_value = fixed_dt + mock_datetime.timezone = timezone + + date_header = http_date() + + mock_datetime.now.assert_called_once_with(timezone.utc) + assert date_header == "Tue, 08 Apr 2025 12:00:00 GMT" diff --git a/xcover/utils.py b/xcover/utils.py index cb8741a..be99096 100644 --- a/xcover/utils.py +++ b/xcover/utils.py @@ -1,8 +1,6 @@ -from datetime import datetime -from time import mktime -from wsgiref.handlers import format_date_time +from datetime import datetime, timezone def http_date(): - now = datetime.utcnow() - return format_date_time(mktime(now.timetuple())) + now = datetime.now(timezone.utc) + return now.strftime("%a, %d %b %Y %H:%M:%S GMT") # RFC 7231 format