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
5 changes: 3 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.13'
cache: pip

- name: Install ruff
run: |
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/specs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14']

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5

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

- name: Install dependencies
run: |
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
master
------

7.3.0 (2026-09-07)
------------------

- add ``PaymentRequiredError`` for HTTP 402 responses
- raise the ``requests`` minimum to ``2.32.5``
- pin ``ruff`` to ``0.15.22``
- test on Python 3.9–3.14

7.2.0 (2026-06-09)
------------------

Expand Down
2 changes: 1 addition & 1 deletion DEVELOPMENT.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Test

$ make test

Runs ``python3 -m unittest -v castle.test``. CI runs the same suite on Python 3.9–3.13 via GitHub Actions (``.github/workflows/specs.yml``).
Runs ``python3 -m unittest -v castle.test``. CI runs the same suite on Python 3.9–3.14 via GitHub Actions (``.github/workflows/specs.yml``).

Linting
-------
Expand Down
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ All exceptions inherit from ``CastleError``. The most useful ones:
- ``InvalidRequestTokenError`` — the request token is missing or invalid
- ``InvalidParametersError`` — 422 response with validation details
- ``RateLimitError`` — 429 response; back off and retry
- ``PaymentRequiredError`` — 402 response
- ``UnauthorizedError`` — 401; bad API secret
- ``InternalServerError`` — 5xx response from Castle
- ``WebhookVerificationError`` — webhook signature did not match
Expand Down
2 changes: 2 additions & 0 deletions castle/core/process_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
InternalServerError,
InvalidRequestTokenError,
RateLimitError,
PaymentRequiredError,
)
from castle.logger import Logger

RESPONSE_ERRORS = {
400: BadRequestError,
401: UnauthorizedError,
402: PaymentRequiredError,
403: ForbiddenError,
404: NotFoundError,
419: UserUnauthorizedError,
Expand Down
4 changes: 4 additions & 0 deletions castle/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,9 @@ class RateLimitError(APIError):
pass


class PaymentRequiredError(APIError):
pass


class InternalServerError(APIError):
pass
5 changes: 5 additions & 0 deletions castle/test/core/process_response_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
InternalServerError,
InvalidRequestTokenError,
RateLimitError,
PaymentRequiredError,
)


Expand Down Expand Up @@ -91,6 +92,10 @@ def test_verify_419(self):
with self.assertRaises(UserUnauthorizedError):
CoreProcessResponse(response(status_code=419)).verify()

def test_verify_402(self):
with self.assertRaises(PaymentRequiredError):
CoreProcessResponse(response(status_code=402)).verify()

def test_verify_429(self):
with self.assertRaises(RateLimitError):
CoreProcessResponse(response(status_code=429)).verify()
Expand Down
2 changes: 1 addition & 1 deletion castle/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION = '7.2.0'
VERSION = '7.3.0'
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ authors = [
requires-python = ">=3.9"
dynamic = ["version"]
dependencies = [
"requests>=2.31",
"requests>=2.32.5",
]
classifiers = [
"Environment :: Web Environment",
Expand All @@ -27,6 +27,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]

[project.urls]
Expand All @@ -36,7 +37,7 @@ Changelog = "https://github.com/castle/castle-python/blob/master/CHANGELOG.rst"

[project.optional-dependencies]
test = ["responses>=0.23"]
lint = ["ruff>=0.6"]
lint = ["ruff==0.15.22"]

[tool.setuptools.dynamic]
version = { attr = "castle.version.VERSION" }
Expand Down