From a4e9e47b330ec29219cba2224566e3ba196ffb2b Mon Sep 17 00:00:00 2001 From: voj-tech-j Date: Wed, 22 Apr 2026 16:43:12 +0200 Subject: [PATCH 1/3] feat: sync webhook API --- .../there-are-changes-in-idempotent-star.md | 71 ++++++++++++++++++ CHANGELOG.md | 13 ++++ README.md | 2 +- .../__pycache__/__init__.cpython-313.pyc | Bin 5768 -> 5768 bytes src/lettr/__pycache__/_client.cpython-313.pyc | Bin 5385 -> 5385 bytes .../__pycache__/webhooks.cpython-313.pyc | Bin 6775 -> 7491 bytes src/lettr/resources/webhooks.py | 30 ++++++-- ...test_webhooks.cpython-313-pytest-9.0.3.pyc | Bin 17501 -> 20333 bytes tests/test_webhooks.py | 41 ++++++++-- 9 files changed, 145 insertions(+), 12 deletions(-) create mode 100644 .claude/plans/there-are-changes-in-idempotent-star.md diff --git a/.claude/plans/there-are-changes-in-idempotent-star.md b/.claude/plans/there-are-changes-in-idempotent-star.md new file mode 100644 index 0000000..309d63e --- /dev/null +++ b/.claude/plans/there-are-changes-in-idempotent-star.md @@ -0,0 +1,71 @@ +# Webhook API changes: namespaced events + `target` → `url` on update + +## Context + +The Lettr API has changed on the webhook endpoints in two ways: + +1. **Event types are now namespaced**, e.g. `message.delivery`, `engagement.click`, `unsubscribe.list_unsubscribe`. Both `POST /webhooks` and `PUT /webhooks/{id}` expect namespaced strings in the `events` field, and `event_types` comes back namespaced in responses. +2. **`PUT /webhooks/{id}` now takes `url` instead of `target`** for changing the webhook endpoint URL. `POST` already uses `url`; this aligns `PUT` with it. + +The SDK currently: +- Passes the caller's `events` list straight through as strings, so no validation code needs changing — only docs/tests that still show the old bare names (`delivery`, `bounce`, `spam_complaint`). +- Sends `payload["target"]` from a `target=` kwarg on `webhooks.update()` (`src/lettr/resources/webhooks.py:132,170`), which will break against the new API. + +Per user direction: `target` must remain accepted and be marked deprecated (emit `DeprecationWarning`, still map to `url` on the wire). No major version bump. + +## Changes + +### 1. `src/lettr/resources/webhooks.py` — `update()` method + +- Add `url: str | None = None` kwarg alongside the existing `target: str | None = None` (keep `target` for backward compat). +- At the top of the method body, if `target is not None` emit `warnings.warn("The `target` parameter is deprecated; use `url` instead.", DeprecationWarning, stacklevel=2)`. If both are passed, raise `TypeError` (ambiguous). +- Resolve `effective_url = url if url is not None else target`; write `payload["url"] = effective_url` when set. Remove the `payload["target"] = ...` line. +- Update the docstring: document `url` as the new parameter, note `target` is deprecated alias, and in the `events` arg doc mention the namespaced format with one example (e.g. `"message.delivery"`). +- Add `import warnings` at the top. + +### 2. `src/lettr/resources/webhooks.py` — `create()` docstring only + +- Update the `events` arg docstring to mention namespaced format, matching the same example style. No code change; the field passthrough already works. + +### 3. `src/lettr/resources/webhooks.py` — class-level `Usage` docstring + +- Leave the example at line 31 alone (it uses `events_mode="all"`, no events list). + +### 4. `tests/test_webhooks.py` + +- `WEBHOOK_DATA["event_types"]` (line 25): change to `["message.delivery", "message.bounce"]`. +- `TestList.test_list_webhooks` (line 40): update assertion to the namespaced list. +- `TestCreate.test_create_webhook` (lines 62, 72): use namespaced events in input and assertion. +- `TestUpdate.test_update_partial` (lines 126, 128): use namespaced events; assert `payload == {"events": ["message.delivery"]}`. +- Add `TestUpdate.test_update_with_url`: call `webhooks.update("wh_123", url="https://new.example.com/hook")`, assert `payload == {"url": "https://new.example.com/hook"}`. +- Add `TestUpdate.test_update_target_deprecated`: use `pytest.warns(DeprecationWarning)`, call `webhooks.update("wh_123", target="https://legacy.example.com/hook")`, assert the payload still sends `{"url": "https://legacy.example.com/hook"}` (deprecated kwarg, modern wire format). +- Add `TestUpdate.test_update_url_and_target_conflict`: passing both raises `TypeError`. + +### 5. `README.md` — Webhooks section + +- Line 263: change `events=["delivery", "bounce", "spam_complaint"]` to `events=["message.delivery", "message.bounce", "message.spam_complaint"]`. + +### 6. `CHANGELOG.md` — `[Unreleased]` + +Add a short entry under `[Unreleased]`: +- **Changed:** Webhook event types are now namespaced (e.g. `message.delivery`, `engagement.click`). Docs/tests updated; the SDK continues to pass `events` strings through unchanged, so callers just need to use the new names. +- **Deprecated:** `webhooks.update(..., target=...)` — use `url=` instead. `target` still works (mapped to `url` in the request body) but emits `DeprecationWarning`. + +## Files touched + +- `src/lettr/resources/webhooks.py` +- `tests/test_webhooks.py` +- `README.md` +- `CHANGELOG.md` + +## Files intentionally NOT touched + +- `src/lettr/_types.py` — `Webhook.event_types: list[str] | None` already accepts namespaced strings; no schema change. +- `_parse_webhook()` at `src/lettr/resources/webhooks.py:12` — reads `event_types` passthrough; already correct for the new format. + +## Verification + +1. `uv run --extra dev pytest tests/test_webhooks.py -v` — all existing tests pass with namespaced data; new `url` / `target`-deprecation / conflict tests pass. +2. `uv run --extra dev pytest` — full suite stays green (no other file depends on webhook event naming). +3. `uv run --extra dev python -c "import warnings; warnings.simplefilter('error', DeprecationWarning); from unittest.mock import MagicMock; from lettr.resources.webhooks import Webhooks; w = Webhooks(MagicMock()); w._client.put.return_value = {'data': {'id':'x','name':'n','url':'u','enabled':True,'auth_type':'none','has_auth_credentials':False}}; w.update('x', target='https://t')"` — should raise `DeprecationWarning` (proves the warning fires). +4. Manually spot-check the README snippet renders the new event names. diff --git a/CHANGELOG.md b/CHANGELOG.md index ae81817..65a1538 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed +- Webhook event types are now namespaced (e.g. `message.delivery`, + `engagement.click`, `unsubscribe.list_unsubscribe`). The SDK continues to + pass `events` strings through unchanged, so callers just need to switch to + the new names. Docs and tests updated accordingly. +- `webhooks.update()` now sends the webhook URL as `url` instead of `target` + to match the updated API. + +### Deprecated +- `webhooks.update(..., target=...)` — use `url=` instead. `target` still + works (mapped to `url` in the request body) but emits a + `DeprecationWarning`. Passing both raises `TypeError`. + ## [1.0.0] - 2026-04-20 ### Changed diff --git a/README.md b/README.md index 742a887..56d7d90 100644 --- a/README.md +++ b/README.md @@ -260,7 +260,7 @@ webhook = client.webhooks.create( url="https://example.com/webhook", auth_type="none", events_mode="selected", - events=["delivery", "bounce", "spam_complaint"], + events=["message.delivery", "message.bounce", "message.spam_complaint"], ) # Create with authentication diff --git a/src/lettr/__pycache__/__init__.cpython-313.pyc b/src/lettr/__pycache__/__init__.cpython-313.pyc index ffef53313683b5f6b99164fa8efa7ca314034116..8d4e4c8ab0c9b9990ae80659c5fb5c86c884f7ca 100644 GIT binary patch delta 20 acmeCs?a<}^%*)Hg00h6*zu3rKD+T~Q$p&oz delta 20 acmeCs?a<}^%*)Hg00ae`&o*+`iU9yO6$Lv0 diff --git a/src/lettr/__pycache__/_client.cpython-313.pyc b/src/lettr/__pycache__/_client.cpython-313.pyc index 71b88e96cbf0fba92fd3900253a5883040b35b3a..ce697ef2ae8650ba7799c2d3030e98b1a402b17d 100644 GIT binary patch delta 20 acmeCw>eS-?%*)Hg00h6*zu3tAPXquzg9hjT delta 20 acmeCw>eS-?%*)Hg00f1c&o*-Z69E7>)&;i! diff --git a/src/lettr/resources/__pycache__/webhooks.cpython-313.pyc b/src/lettr/resources/__pycache__/webhooks.cpython-313.pyc index 62a2c6566023b5a9bb9b51ebfa2a7bf17e218f83..70a096242064585171b2f1204e80d493852934d3 100644 GIT binary patch delta 2058 zcmah~O>7%Q6rSA5Hqu}U5O%A%JcWV znR)N?H*cN$PklcnuS=2u$g}qCpOwteB{>04UfPWIaWh`*RiWyg@lErXM?m$d{EUA( zfCCKsXM)oL76=yAKnlF-#bN?vff`H!RhaP5iU8oyH}9PHK*{!U?+PI|2iJeIFLNLG zcr}<8?Q!q0?QpU^=N*MZ%?sWyAj~x%<4-_1)_lwVBZNDehl5oJFEy_UbDptTZCN+# zT3KH}`f1&;kaf1Mo5-pmte5r5X&sH6S<(#wxsSb7O7F}eJ-?Vo#o~OH95%H@J-?t= z$zFUmo9paES>0G9OUtBazFe)8Pi0ROi}nwZTysUzp|p>PH$Nufb>JMZ|Byckh?v@j zMf+`KPeUY-Cx09OaQ!(5z-3VImbL&;;7Vj|o@Crdg%cZChw~dQ0dU0IS?_%kFFo_L zCVNy)^-gk#R5iG9U`Pc|iJUpMRrPHq>kZO|(%mXgX~Dq`=&p7+LzK^&ST(w^b#~YT07j5kHhh4kf$Wg@M6zfb32$gEqQl~1?j0GXLF-RooDk&Bb)+#2MxlX}3GJ$(BuHj;{79NBz8~-<=?mTvd zJ$x?zV;-+Wt~bt2942y+Ua^*R;sLb)Q8P9KqLGEJSED&()GYS3^5=HUE$O{obqy1t z7O7A%QSZb~v|^H7tZ2nBEnQp4V|q!Wuq~LDRz9Uv$(vW*7=E%~uPKk(SNaEz``f{; z7wy0q*IcvhrKlbGx9@m}oNjaV6${5`0|jTu2hP#pzFHLRB4MKiuT0Vmoj6k=0ojpg zPJffqzeyl(<}nCDk!#{mONp#DZp1dVqBHB9CmwNtCmgxU18LyHgYO+|^-bUC%eDs7 zcl=&Sb_CF$y!iaB?C?c@OH{6jgRM+!0Yz5*a0|gUx7*H{l`9XrnYGDJ;uOELv4NBg?DUPHGyU3ggQ z?Q~(5hTSBbv%ic>>7EAf0~%O%#=aIm#_y&3_uFHMah~3{IdAKU@y4Vt=kP#@IDU!( zKn^=WiUbgiJ0e9P5KB4|MKVZa9fhJkioz5{Kx)|Orzi?CBhCOtF`A20lmOu^PLiS& z5W@EcDY^hb8nsfH*3cs@WQUXS#?T??%iSXVd=wB7O4123C;&O(hzy26c+im;ltDD( zC=9wn7>rO&{R~E_fB^ z{c|$o!_N}$?0d(sy|Y^7m201E0PFXk^9y0hapkHvj+t delta 1257 zcmZvbTWB0r7{|Xe*PZLS$!7L8yB(9&Cc135#t@9v20~*@!d4s?18SkcMPrw&oLwm_ zE$f>Kr8FEAqzXRyBo1{I-r4!1u;=Eknc3R6XR zMWJRMrXe(n5Sj}T?gT)sPp)2;h|O&I4bw_$X=$z3ZWM%Y?`HV!)uzx0}*s`OsrsJ~@QnRD)oE_q<@=bg1a(Nx% zHMWwzE}PV3Kc!C(@nKZ{lL5%V&m7){2JG4`Xz!Wrmhw%!XowLbMY&AGI~Z?uMj(;ih^j%?u7>O&5_ zuetCeZ4#Kd?@c|j()(5^s!U&7ed}ywW%jLd6x@GpZQm}BtlSOat?=o$($6MIdi59E zop!(d1^Yg~$zNQ#FuQYxPoO%NIgjF-p--UTCy|gdriC%pIsIw&`ZTx{G`qWPdIE>m zP#R-8Ii`mMv5yPY;Ze7I@`$3F=qr|=8ZQ!kMGd|AvTaq$dqCW$%bqtc94|>ZRr^98*P}v24#yL7Zn>N{XzrsHEPmrhBFMfWh#g7aB6TMk3u}lcL i35B~beFxIF!Mh8`ZiD}u<`C^L=tyMoS3spXKKWmw-x1*e diff --git a/src/lettr/resources/webhooks.py b/src/lettr/resources/webhooks.py index b038ca5..aa8e53e 100644 --- a/src/lettr/resources/webhooks.py +++ b/src/lettr/resources/webhooks.py @@ -3,6 +3,7 @@ from __future__ import annotations import builtins +import warnings from typing import Any from .._client import ApiClient @@ -93,7 +94,9 @@ def create( oauth_client_id: OAuth2 client ID (when ``auth_type="oauth2"``). oauth_client_secret: OAuth2 client secret (when ``auth_type="oauth2"``). oauth_token_url: OAuth2 token URL (when ``auth_type="oauth2"``). - events: Event types to receive (when ``events_mode="selected"``). + events: Namespaced event types to receive (when + ``events_mode="selected"``), e.g. ``["message.delivery", + "engagement.click"]``. Returns: A :class:`Webhook` with the created webhook details. @@ -129,6 +132,7 @@ def update( webhook_id: str, *, name: str | None = None, + url: str | None = None, target: str | None = None, auth_type: str | None = None, auth_username: str | None = None, @@ -146,14 +150,18 @@ def update( Args: webhook_id: The webhook ID to update. name: New webhook name. - target: New webhook URL. + url: New webhook URL. + target: Deprecated alias for ``url``. Still accepted but emits a + :class:`DeprecationWarning`; passing both ``url`` and + ``target`` raises :class:`TypeError`. auth_type: New authentication type. auth_username: New basic auth username. auth_password: New basic auth password. oauth_token_url: New OAuth2 token URL. oauth_client_id: New OAuth2 client ID. oauth_client_secret: New OAuth2 client secret. - events: New event types to receive. + events: New namespaced event types to receive, e.g. + ``["message.delivery", "engagement.click"]``. active: Enable or disable the webhook. Returns: @@ -163,11 +171,23 @@ def update( NotFoundError: If the webhook is not found. ValidationError: If validation fails. """ + if target is not None: + if url is not None: + raise TypeError( + "Pass either `url` or `target` (deprecated), not both." + ) + warnings.warn( + "The `target` parameter is deprecated; use `url` instead.", + DeprecationWarning, + stacklevel=2, + ) + url = target + payload: dict[str, Any] = {} if name is not None: payload["name"] = name - if target is not None: - payload["target"] = target + if url is not None: + payload["url"] = url if auth_type is not None: payload["auth_type"] = auth_type if auth_username is not None: diff --git a/tests/__pycache__/test_webhooks.cpython-313-pytest-9.0.3.pyc b/tests/__pycache__/test_webhooks.cpython-313-pytest-9.0.3.pyc index 3eba311c163ba44bb5e6084de7db3fc7629b0ed7..cc869c0c568fef3c300dccd94dec4cfa26404f4b 100644 GIT binary patch delta 2436 zcmaJ@Z){Ul6uOK_sa7qGm>nie@H0#?viQ8p2CkLb-x zXYE(wiLO{Alu&+q1qy}@0NNP0`J!3)27RODHs$ddbEj`F<4UlqRi51{P zNpB(%i#OHO3@XQ~mDfT8v3{jG9380XjYePgVp6~|`xq3^%9e8BBA7Qs`eTb{eVj?d zr4Pb{oVF*RdBGvAd%@#b+oBs8(>mun-cYBLTqEbTqMArT*f6AJqW<`71`jzBE&+m zZ#8#}b#fEeEzrLzOX!_qOOwpWhDMG0&BUfz3RA3LgonQfh~4A zEZ8e#lYS7Q%-7=RjxJ-k?|Q=9#+7=64Rc z$DAd!W|f8Bsh39f_n6z81UBn@egL@iv1^0BIpM%(Rr|kB7)$ zJe}uPVnhjt5`EFZ1HkkR_RzB}^$p}QBtJojrAvjF*>W(VFQG)z9;V0_9^=oj#l8nP ziKYeQtywP4U#mbl zMwn=Ks1Cm>`T>)Ye@fJ!3DM6)yGVdNxr|FLdJur=E3(0bMdr*ci%Jc;nhlSuxr;mR zSvA7ytQd8=??V5pBd@L_Qy^_T5>51yF_@PTk7Hgup~rM{Vj*^f#r7?~ow&^HbQM5Kmq{w8 zC}por6>gq3A#2GDGFoj+FTQCDGTYhhHzj(LqIXiT zI*<>c0D+4Gd9%oFcq6PP*~1{f;2j3 z^V{*X&CIvsRFP}ipcyp{8RNd$I?FR=y1>j=>G7&mCR_#4Ifz!#>#h6n82!8TTaJ86 zZ@0DM52$(jVf+=8ELwAuRcFACTKkT&{}Beh0~3oDqSv;+#cStA>vz29(egW3Lb8sM_*4lUHaXUo8{QEsm7boXoP+qRLxro0l`ib2GATX6IYZ zm}qyMU*#gd$^{O)6;c}_E@;>RSwQk4zuk2XD7pj`;a7ohuW;CPR6>}Sk%U2P4TKK3 z)@vMglLZClaqaG_DPbWY*T=&q8XFxjU^_>d-F-~ z0=aDrUx2~u!uVZ?ja9XX2c)2D@<9PRUapYT;u4qCoYa!kmo1Y;eD(nSWa%Y0`LT}) zW9wuI-vq|_AcGWVgS3E%79cL>01}`WV`g<{gqSva@+RLNj$3R6l_fv}Cp-H^G0vVm z&rg Webhooks: "enabled": True, "auth_type": "none", "has_auth_credentials": False, - "event_types": ["delivery", "bounce"], + "event_types": ["message.delivery", "message.bounce"], "last_successful_at": "2025-06-01", "last_failure_at": None, "last_status": "200", @@ -37,7 +37,7 @@ def test_list_webhooks(self, webhooks: Webhooks, mock_client: MagicMock) -> None assert len(result) == 1 assert isinstance(result[0], Webhook) assert result[0].id == "wh_123" - assert result[0].event_types == ["delivery", "bounce"] + assert result[0].event_types == ["message.delivery", "message.bounce"] class TestGet: @@ -59,7 +59,7 @@ def test_create_webhook(self, webhooks: Webhooks, mock_client: MagicMock) -> Non url="https://example.com/hook", auth_type="none", events_mode="selected", - events=["delivery", "bounce"], + events=["message.delivery", "message.bounce"], ) assert isinstance(result, Webhook) @@ -69,7 +69,7 @@ def test_create_webhook(self, webhooks: Webhooks, mock_client: MagicMock) -> Non assert payload["name"] == "My Hook" assert payload["auth_type"] == "none" assert payload["events_mode"] == "selected" - assert payload["events"] == ["delivery", "bounce"] + assert payload["events"] == ["message.delivery", "message.bounce"] def test_create_with_basic_auth(self, webhooks: Webhooks, mock_client: MagicMock) -> None: mock_client.post.return_value = { @@ -123,11 +123,40 @@ def test_update_webhook(self, webhooks: Webhooks, mock_client: MagicMock) -> Non def test_update_partial(self, webhooks: Webhooks, mock_client: MagicMock) -> None: mock_client.put.return_value = {"data": WEBHOOK_DATA} - webhooks.update("wh_123", events=["delivery"]) + webhooks.update("wh_123", events=["message.delivery"]) payload = mock_client.put.call_args.kwargs["json"] - assert payload == {"events": ["delivery"]} + assert payload == {"events": ["message.delivery"]} assert "name" not in payload + def test_update_with_url(self, webhooks: Webhooks, mock_client: MagicMock) -> None: + mock_client.put.return_value = {"data": WEBHOOK_DATA} + + webhooks.update("wh_123", url="https://new.example.com/hook") + payload = mock_client.put.call_args.kwargs["json"] + assert payload == {"url": "https://new.example.com/hook"} + + def test_update_target_deprecated( + self, webhooks: Webhooks, mock_client: MagicMock + ) -> None: + mock_client.put.return_value = {"data": WEBHOOK_DATA} + + with pytest.warns(DeprecationWarning, match="target"): + webhooks.update("wh_123", target="https://legacy.example.com/hook") + + payload = mock_client.put.call_args.kwargs["json"] + assert payload == {"url": "https://legacy.example.com/hook"} + + def test_update_url_and_target_conflict( + self, webhooks: Webhooks, mock_client: MagicMock + ) -> None: + with pytest.raises(TypeError, match="both"): + webhooks.update( + "wh_123", + url="https://a.example.com/hook", + target="https://b.example.com/hook", + ) + mock_client.put.assert_not_called() + class TestDelete: def test_delete_webhook(self, webhooks: Webhooks, mock_client: MagicMock) -> None: From 9ed761f72d3ba5acc2c328ca6e88f38c3d33d845 Mon Sep 17 00:00:00 2001 From: voj-tech-j Date: Wed, 22 Apr 2026 16:47:39 +0200 Subject: [PATCH 2/3] bump --- CHANGELOG.md | 5 ++++- pyproject.toml | 2 +- src/lettr/__init__.py | 2 +- .../__pycache__/__init__.cpython-313.pyc | Bin 5768 -> 5768 bytes src/lettr/__pycache__/_client.cpython-313.pyc | Bin 5385 -> 5385 bytes src/lettr/_client.py | 4 ++-- .../__pycache__/webhooks.cpython-313.pyc | Bin 7491 -> 7485 bytes src/lettr/resources/webhooks.py | 4 +--- ...test_webhooks.cpython-313-pytest-9.0.3.pyc | Bin 20333 -> 20292 bytes tests/test_webhooks.py | 4 +--- 10 files changed, 10 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65a1538..3cdaa20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.1.0] - 2026-04-22 + ### Changed - Webhook event types are now namespaced (e.g. `message.delivery`, `engagement.click`, `unsubscribe.list_unsubscribe`). The SDK continues to @@ -127,7 +129,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `ValidationError`, `NotFoundError`, `ConflictError`, `BadRequestError`, `ServerError`) -[Unreleased]: https://github.com/lettr/lettr-python/compare/v1.0.0...HEAD +[Unreleased]: https://github.com/lettr/lettr-python/compare/v1.1.0...HEAD +[1.1.0]: https://github.com/lettr/lettr-python/compare/v1.0.0...v1.1.0 [1.0.0]: https://github.com/lettr/lettr-python/compare/v0.3.0...v1.0.0 [0.3.0]: https://github.com/lettr/lettr-python/compare/v0.2.0...v0.3.0 [0.2.0]: https://github.com/lettr/lettr-python/compare/v0.1.0...v0.2.0 diff --git a/pyproject.toml b/pyproject.toml index 9b4e1cf..4cdb4d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "lettr" -version = "1.0.0" +version = "1.1.0" description = "Official Python SDK for the Lettr Email API" readme = "README.md" license = "MIT" diff --git a/src/lettr/__init__.py b/src/lettr/__init__.py index 94cd32c..b3c8c0a 100644 --- a/src/lettr/__init__.py +++ b/src/lettr/__init__.py @@ -61,7 +61,7 @@ ) from .resources import Domains, Emails, Projects, Templates, Webhooks -__version__ = "1.0.0" +__version__ = "1.1.0" __all__ = [ # Client diff --git a/src/lettr/__pycache__/__init__.cpython-313.pyc b/src/lettr/__pycache__/__init__.cpython-313.pyc index 8d4e4c8ab0c9b9990ae80659c5fb5c86c884f7ca..bd572bea01b2622fe192630601fc9b7f5c0d2531 100644 GIT binary patch delta 26 gcmeCs?a<}=%*)Hg00c(&H*)=AVKm&#%GxXl0A67R*#H0l delta 26 gcmeCs?a<}=%*)Hg00h6*Z{+&L!f3FWm9<$A0A@o6Z~y=R diff --git a/src/lettr/__pycache__/_client.cpython-313.pyc b/src/lettr/__pycache__/_client.cpython-313.pyc index ce697ef2ae8650ba7799c2d3030e98b1a402b17d..3ae0fa2c0fc09c6bfa6e289ed00e5c84ee0441b0 100644 GIT binary patch delta 26 gcmeCw>eS-;%*)Hg00d_DH*#4rGa7DoVLmDd09fD#mH+?% delta 26 gcmeCw>eS-;%*)Hg00h6*Z{)IMW;EFB!hBQ^0AP*>DF6Tf diff --git a/src/lettr/_client.py b/src/lettr/_client.py index dc84307..8017ce3 100644 --- a/src/lettr/_client.py +++ b/src/lettr/_client.py @@ -31,7 +31,7 @@ def __init__( "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", "Accept": "application/json", - "User-Agent": "lettr-python/1.0.0", + "User-Agent": "lettr-python/1.1.0", }, ) @@ -98,7 +98,7 @@ def get_no_auth(self, path: str, *, params: dict[str, Any] | None = None) -> Any timeout=self._timeout, headers={ "Accept": "application/json", - "User-Agent": "lettr-python/1.0.0", + "User-Agent": "lettr-python/1.1.0", }, ) except httpx.HTTPError as exc: diff --git a/src/lettr/resources/__pycache__/webhooks.cpython-313.pyc b/src/lettr/resources/__pycache__/webhooks.cpython-313.pyc index 70a096242064585171b2f1204e80d493852934d3..e7cb5d84be7e784946b2b77869ce6f0e2171d4d7 100644 GIT binary patch delta 240 zcmW;HKM%oB6b116NE51myn0@XD#0LPm-IWBHIbNE?ZRp{`w(I_Sq&8igM`s|LxjYl z@1Ei0cgC|1ccJw%O&yX9Z;#2>-&kwe{3de&7%?!MW3GC!o#p&0YjJ&Wl2M$Gu7=p2 z<&UxBHukjiyw9}mUAU+zUpk)!QXYo&v-cwj&`iE-V;<$-SpWXn;=4w diff --git a/src/lettr/resources/webhooks.py b/src/lettr/resources/webhooks.py index aa8e53e..6be82ca 100644 --- a/src/lettr/resources/webhooks.py +++ b/src/lettr/resources/webhooks.py @@ -173,9 +173,7 @@ def update( """ if target is not None: if url is not None: - raise TypeError( - "Pass either `url` or `target` (deprecated), not both." - ) + raise TypeError("Pass either `url` or `target` (deprecated), not both.") warnings.warn( "The `target` parameter is deprecated; use `url` instead.", DeprecationWarning, diff --git a/tests/__pycache__/test_webhooks.cpython-313-pytest-9.0.3.pyc b/tests/__pycache__/test_webhooks.cpython-313-pytest-9.0.3.pyc index cc869c0c568fef3c300dccd94dec4cfa26404f4b..e87e655aa2f76f2fc9e69ee903fd9db86b550a77 100644 GIT binary patch delta 119 zcmaDmkMYPnM&8f7yj%=G5Pkne=9`VY=ZzVICf_yI-z;JBNSNsW!{iC}qML<1W-u{M zp1j8EAfwsjJZ~|MFMRB*u8bdqCNKBSVVu8N#D|%YalvE>-zFeuw(kx`DQ!lbj|@QK TdkiBBqdVg#1`t`q1GEPK-tZ;r delta 164 zcmX>ykMZq1M&8f7yj%=Guz1sp%wHRM&l@wwO}=Za&m+fxfSY+t9tm?F0;+0Y_`t@X zslWNV`!XiRsgvh<9b^ogoZu~{{DF^?)s^vvgu(}AFhk!0!g#>R`-K%G@i}F(Fw6h| diff --git a/tests/test_webhooks.py b/tests/test_webhooks.py index 9188ab5..e01b353 100644 --- a/tests/test_webhooks.py +++ b/tests/test_webhooks.py @@ -135,9 +135,7 @@ def test_update_with_url(self, webhooks: Webhooks, mock_client: MagicMock) -> No payload = mock_client.put.call_args.kwargs["json"] assert payload == {"url": "https://new.example.com/hook"} - def test_update_target_deprecated( - self, webhooks: Webhooks, mock_client: MagicMock - ) -> None: + def test_update_target_deprecated(self, webhooks: Webhooks, mock_client: MagicMock) -> None: mock_client.put.return_value = {"data": WEBHOOK_DATA} with pytest.warns(DeprecationWarning, match="target"): From 481ff5e0d06556fb7a90969a5067f3e2d07dbef7 Mon Sep 17 00:00:00 2001 From: voj-tech-j Date: Wed, 22 Apr 2026 16:51:45 +0200 Subject: [PATCH 3/3] chore: add .gitignore; untrack __pycache__ and stale plan file --- .../there-are-changes-in-idempotent-star.md | 71 ------------------ .gitignore | 23 ++++++ .../__pycache__/__init__.cpython-313.pyc | Bin 5768 -> 0 bytes src/lettr/__pycache__/_client.cpython-313.pyc | Bin 5385 -> 0 bytes .../__pycache__/_exceptions.cpython-313.pyc | Bin 6247 -> 0 bytes src/lettr/__pycache__/_types.cpython-313.pyc | Bin 17283 -> 0 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 480 -> 0 bytes .../__pycache__/domains.cpython-313.pyc | Bin 5879 -> 0 bytes .../__pycache__/emails.cpython-313.pyc | Bin 21772 -> 0 bytes .../__pycache__/projects.cpython-313.pyc | Bin 2126 -> 0 bytes .../__pycache__/templates.cpython-313.pyc | Bin 10157 -> 0 bytes .../__pycache__/webhooks.cpython-313.pyc | Bin 7485 -> 0 bytes tests/__pycache__/__init__.cpython-313.pyc | Bin 164 -> 0 bytes .../conftest.cpython-313-pytest-9.0.3.pyc | Bin 873 -> 0 bytes .../test_client.cpython-313-pytest-9.0.3.pyc | Bin 9715 -> 0 bytes .../test_domains.cpython-313-pytest-9.0.3.pyc | Bin 29672 -> 0 bytes .../test_emails.cpython-313-pytest-9.0.3.pyc | Bin 54261 -> 0 bytes ...st_exceptions.cpython-313-pytest-9.0.3.pyc | Bin 14861 -> 0 bytes .../test_lettr.cpython-313-pytest-9.0.3.pyc | Bin 13087 -> 0 bytes ...test_projects.cpython-313-pytest-9.0.3.pyc | Bin 6817 -> 0 bytes ...est_templates.cpython-313-pytest-9.0.3.pyc | Bin 30449 -> 0 bytes .../test_types.cpython-313-pytest-9.0.3.pyc | Bin 14917 -> 0 bytes ...test_webhooks.cpython-313-pytest-9.0.3.pyc | Bin 20292 -> 0 bytes 23 files changed, 23 insertions(+), 71 deletions(-) delete mode 100644 .claude/plans/there-are-changes-in-idempotent-star.md create mode 100644 .gitignore delete mode 100644 src/lettr/__pycache__/__init__.cpython-313.pyc delete mode 100644 src/lettr/__pycache__/_client.cpython-313.pyc delete mode 100644 src/lettr/__pycache__/_exceptions.cpython-313.pyc delete mode 100644 src/lettr/__pycache__/_types.cpython-313.pyc delete mode 100644 src/lettr/resources/__pycache__/__init__.cpython-313.pyc delete mode 100644 src/lettr/resources/__pycache__/domains.cpython-313.pyc delete mode 100644 src/lettr/resources/__pycache__/emails.cpython-313.pyc delete mode 100644 src/lettr/resources/__pycache__/projects.cpython-313.pyc delete mode 100644 src/lettr/resources/__pycache__/templates.cpython-313.pyc delete mode 100644 src/lettr/resources/__pycache__/webhooks.cpython-313.pyc delete mode 100644 tests/__pycache__/__init__.cpython-313.pyc delete mode 100644 tests/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc delete mode 100644 tests/__pycache__/test_client.cpython-313-pytest-9.0.3.pyc delete mode 100644 tests/__pycache__/test_domains.cpython-313-pytest-9.0.3.pyc delete mode 100644 tests/__pycache__/test_emails.cpython-313-pytest-9.0.3.pyc delete mode 100644 tests/__pycache__/test_exceptions.cpython-313-pytest-9.0.3.pyc delete mode 100644 tests/__pycache__/test_lettr.cpython-313-pytest-9.0.3.pyc delete mode 100644 tests/__pycache__/test_projects.cpython-313-pytest-9.0.3.pyc delete mode 100644 tests/__pycache__/test_templates.cpython-313-pytest-9.0.3.pyc delete mode 100644 tests/__pycache__/test_types.cpython-313-pytest-9.0.3.pyc delete mode 100644 tests/__pycache__/test_webhooks.cpython-313-pytest-9.0.3.pyc diff --git a/.claude/plans/there-are-changes-in-idempotent-star.md b/.claude/plans/there-are-changes-in-idempotent-star.md deleted file mode 100644 index 309d63e..0000000 --- a/.claude/plans/there-are-changes-in-idempotent-star.md +++ /dev/null @@ -1,71 +0,0 @@ -# Webhook API changes: namespaced events + `target` → `url` on update - -## Context - -The Lettr API has changed on the webhook endpoints in two ways: - -1. **Event types are now namespaced**, e.g. `message.delivery`, `engagement.click`, `unsubscribe.list_unsubscribe`. Both `POST /webhooks` and `PUT /webhooks/{id}` expect namespaced strings in the `events` field, and `event_types` comes back namespaced in responses. -2. **`PUT /webhooks/{id}` now takes `url` instead of `target`** for changing the webhook endpoint URL. `POST` already uses `url`; this aligns `PUT` with it. - -The SDK currently: -- Passes the caller's `events` list straight through as strings, so no validation code needs changing — only docs/tests that still show the old bare names (`delivery`, `bounce`, `spam_complaint`). -- Sends `payload["target"]` from a `target=` kwarg on `webhooks.update()` (`src/lettr/resources/webhooks.py:132,170`), which will break against the new API. - -Per user direction: `target` must remain accepted and be marked deprecated (emit `DeprecationWarning`, still map to `url` on the wire). No major version bump. - -## Changes - -### 1. `src/lettr/resources/webhooks.py` — `update()` method - -- Add `url: str | None = None` kwarg alongside the existing `target: str | None = None` (keep `target` for backward compat). -- At the top of the method body, if `target is not None` emit `warnings.warn("The `target` parameter is deprecated; use `url` instead.", DeprecationWarning, stacklevel=2)`. If both are passed, raise `TypeError` (ambiguous). -- Resolve `effective_url = url if url is not None else target`; write `payload["url"] = effective_url` when set. Remove the `payload["target"] = ...` line. -- Update the docstring: document `url` as the new parameter, note `target` is deprecated alias, and in the `events` arg doc mention the namespaced format with one example (e.g. `"message.delivery"`). -- Add `import warnings` at the top. - -### 2. `src/lettr/resources/webhooks.py` — `create()` docstring only - -- Update the `events` arg docstring to mention namespaced format, matching the same example style. No code change; the field passthrough already works. - -### 3. `src/lettr/resources/webhooks.py` — class-level `Usage` docstring - -- Leave the example at line 31 alone (it uses `events_mode="all"`, no events list). - -### 4. `tests/test_webhooks.py` - -- `WEBHOOK_DATA["event_types"]` (line 25): change to `["message.delivery", "message.bounce"]`. -- `TestList.test_list_webhooks` (line 40): update assertion to the namespaced list. -- `TestCreate.test_create_webhook` (lines 62, 72): use namespaced events in input and assertion. -- `TestUpdate.test_update_partial` (lines 126, 128): use namespaced events; assert `payload == {"events": ["message.delivery"]}`. -- Add `TestUpdate.test_update_with_url`: call `webhooks.update("wh_123", url="https://new.example.com/hook")`, assert `payload == {"url": "https://new.example.com/hook"}`. -- Add `TestUpdate.test_update_target_deprecated`: use `pytest.warns(DeprecationWarning)`, call `webhooks.update("wh_123", target="https://legacy.example.com/hook")`, assert the payload still sends `{"url": "https://legacy.example.com/hook"}` (deprecated kwarg, modern wire format). -- Add `TestUpdate.test_update_url_and_target_conflict`: passing both raises `TypeError`. - -### 5. `README.md` — Webhooks section - -- Line 263: change `events=["delivery", "bounce", "spam_complaint"]` to `events=["message.delivery", "message.bounce", "message.spam_complaint"]`. - -### 6. `CHANGELOG.md` — `[Unreleased]` - -Add a short entry under `[Unreleased]`: -- **Changed:** Webhook event types are now namespaced (e.g. `message.delivery`, `engagement.click`). Docs/tests updated; the SDK continues to pass `events` strings through unchanged, so callers just need to use the new names. -- **Deprecated:** `webhooks.update(..., target=...)` — use `url=` instead. `target` still works (mapped to `url` in the request body) but emits `DeprecationWarning`. - -## Files touched - -- `src/lettr/resources/webhooks.py` -- `tests/test_webhooks.py` -- `README.md` -- `CHANGELOG.md` - -## Files intentionally NOT touched - -- `src/lettr/_types.py` — `Webhook.event_types: list[str] | None` already accepts namespaced strings; no schema change. -- `_parse_webhook()` at `src/lettr/resources/webhooks.py:12` — reads `event_types` passthrough; already correct for the new format. - -## Verification - -1. `uv run --extra dev pytest tests/test_webhooks.py -v` — all existing tests pass with namespaced data; new `url` / `target`-deprecation / conflict tests pass. -2. `uv run --extra dev pytest` — full suite stays green (no other file depends on webhook event naming). -3. `uv run --extra dev python -c "import warnings; warnings.simplefilter('error', DeprecationWarning); from unittest.mock import MagicMock; from lettr.resources.webhooks import Webhooks; w = Webhooks(MagicMock()); w._client.put.return_value = {'data': {'id':'x','name':'n','url':'u','enabled':True,'auth_type':'none','has_auth_credentials':False}}; w.update('x', target='https://t')"` — should raise `DeprecationWarning` (proves the warning fires). -4. Manually spot-check the README snippet renders the new event names. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3bdc508 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +*.egg-info/ +dist/ +build/ + +# Virtual environments +.venv/ +venv/ +env/ + +# Tooling caches +.pytest_cache/ +.ruff_cache/ +.mypy_cache/ + +# Claude local files +.claude/ + +# OS +.DS_Store diff --git a/src/lettr/__pycache__/__init__.cpython-313.pyc b/src/lettr/__pycache__/__init__.cpython-313.pyc deleted file mode 100644 index bd572bea01b2622fe192630601fc9b7f5c0d2531..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5768 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 b4lG6zB@!x!H(hG_PMYSp=syTj=Ieg|bBT$v diff --git a/src/lettr/__pycache__/_exceptions.cpython-313.pyc b/src/lettr/__pycache__/_exceptions.cpython-313.pyc deleted file mode 100644 index fee331837a3f6d0f6806ebbaf3ba245aa983d85b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6247 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 diff --git a/src/lettr/__pycache__/_types.cpython-313.pyc b/src/lettr/__pycache__/_types.cpython-313.pyc deleted file mode 100644 index 4b723587068c938866e384da25cff6a9221d1e82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17283 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 E0Ut&74*&oF diff --git a/src/lettr/resources/__pycache__/__init__.cpython-313.pyc b/src/lettr/resources/__pycache__/__init__.cpython-313.pyc deleted file mode 100644 index 9dc38ec7b39aa7c5800bce8831ed53752ea4c11e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 480 zcmXw#%}N6?6ov0}ep?m9r4|{NUD&*U2tr*rQ>0}Sm!VFB{h2nyO{%mzAHs+5Eqo1w z-6$?x2tr@LByF=ed`a#-=W(92K_sq&J)jjlrd+!cf#fK4Q5vT)knFvgk=>KknH5fb+3v_~>c_^o;mM z0wbZ8>&C7MDed!|QWf^s_O@CD%qG|_6_uM1+pnr}n`5n1^t6exrpB>X6qLTgN@sxT zl3T%0kVig}EFX;cY|$evCdQJN#Ew6fb5fWEoR)Jr;8P+nUq6uTHUyz`I2}q#o8??Z pXY1vh#b|6yrt(;v#>WygG1fpE#u{lO5juqZ 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 TAR9;?clveo_vh0`@? diff --git a/src/lettr/resources/__pycache__/emails.cpython-313.pyc b/src/lettr/resources/__pycache__/emails.cpython-313.pyc deleted file mode 100644 index d5cf89969a098dd853ecae57e5d283279d2c67a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21772 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 EzkD(eN&o-= diff --git a/src/lettr/resources/__pycache__/templates.cpython-313.pyc b/src/lettr/resources/__pycache__/templates.cpython-313.pyc deleted file mode 100644 index 993d0fef501d4ee50fe1188e5e9387d29ab1e28f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10157 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 diff --git a/tests/__pycache__/test_client.cpython-313-pytest-9.0.3.pyc b/tests/__pycache__/test_client.cpython-313-pytest-9.0.3.pyc deleted file mode 100644 index 6d88fdb833e382a7885971195f05982e566fbc93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9715 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 MNB)NcLKo@(05Z#OWdHyG diff --git a/tests/__pycache__/test_domains.cpython-313-pytest-9.0.3.pyc b/tests/__pycache__/test_domains.cpython-313-pytest-9.0.3.pyc deleted file mode 100644 index e17a1d4f217f4db3a4ac3fcd84efdfefb38f2422..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29672 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 Z&&GWL-$}@ce%A1c&)4@K3Q^uJ{|olSd7S_N diff --git a/tests/__pycache__/test_emails.cpython-313-pytest-9.0.3.pyc b/tests/__pycache__/test_emails.cpython-313-pytest-9.0.3.pyc deleted file mode 100644 index a831e5b62ac84e03b13166e701c2fa88ca08fbec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54261 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 diff --git a/tests/__pycache__/test_exceptions.cpython-313-pytest-9.0.3.pyc b/tests/__pycache__/test_exceptions.cpython-313-pytest-9.0.3.pyc deleted file mode 100644 index 85109149246d9cc1194ab32cb5edb54abca3b487..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14861 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 diff --git a/tests/__pycache__/test_lettr.cpython-313-pytest-9.0.3.pyc b/tests/__pycache__/test_lettr.cpython-313-pytest-9.0.3.pyc deleted file mode 100644 index 4a82d516b93f4f230030eaa729449dfb05ba719a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13087 zcmeHOUu+b|8Q;CX337Zm#K)q~FdhM3i_2?gyae!CU0w&{C4rZ6c^js}QrmpjNzE{g%vqgg%xNw2 zhGv>HGou#EnL??kl}-3k4I_6S2b4ssRV|lwQ#Ffv*%*Uz%L#R=SU8~<&P!pdp?pJlN1!51SV$IWSdPn~ZNj+-OjTSCvs@H% z5tfU|Q5v6$NyOTSinERngDxhm6il7oPeOME(Kk{I@?k*`AAAIv8^VNJHEyfmG9Z%` zChS!d*xDTkg@lYS0V~au93Hm&hLvLfoY~9>Q^HQ6Pw2KKCqeEktZ*l^$GXvQr*Kx3 zB4hL0)!CwQUYpCzs#KlPOpRuWMuuwdRf<%bgei^AsAgf>5~PR~o1HV^DXkb)i-u-c ziBoE+q8+7FrxcX}>4>3~&Kjsy#yZ-cH#BPWU(nB)T4DN}UYS?>k7&kuQ=jdBlj`TR z^X6QC372>;^gOMX`>}h2QHAkyvvbx~WGdRstU0IH$||-3xu8kUJyt#iY8iWgd?egU zZMgRCPu~6Y!Rp>O7E>qgCEKrOuYT`gSZEs)ms2N}QYRi61SEfz><|AwF&b}JM0{4Z zh^OK8gGI#0Wl0vD1u4U;Rt`;o6i=r+oTbtCyNmJjHPk*`a3254V%W@N{%+pi0Zb6*0?*HQc&yfi*iJcK9!cwHH;IeW!{}DSG!FO ztpc_4T7gzk-%JEchnyK$Q__8v*&kEE$Op>`Z2qu?8fg8#((VqmME6ONNxVWW}dd zLxs+)826(9&4*{_29WGSvLDH?6`$16*)psa699Kfg`q8SQ9CoO>*paii=e$=LXQmZ z(=DL9m3(D(PB~L4mP~9IE9nKb1ik@q84y>gwM8+e^-5_{q1r4}rb_x5wWO56+pt;` zLp`e@+iE++9t=D==1^E06mSB;_fWL=L6I`^@vLZ}q#K$PrR^{>-HOAv;_!S@2K|L0 zUf`XK7*UYTV4@w^Y7^6~Ks9_s(96&(v;Ys=dlDwQ*^T2K#VTRc!MFin8{CQZP1iqI zY~OV`w$k~0m2_Xdc>Tg+x*Kx!boVl8_|&l4;kzu=c}N_EnG^L<{iNV==5 zx?UjNE1fW^#K)H)S5HgJq~TM;YM0ko;_M|N;fQuCkZ?+MBHf(h6^lfwuIhS$NGqK^ zRnp7H?}c1F-MdU0J~ga%d5tB`ULw6XqTLE4oKl_i-u!@9ERx>ps;(DE?@A{;bq^mO zH0i0QdzMMVr-s!oud&40OQZ)!v|E9MQ>v4moAbP4k@Qqob-h4(zV-1*+qLAC=wL!n_in&E3h zP|L;y?v(4cfs5xlkK=(Zo?|jy=h%&yjJGxRi=`m<)_ET09DA(;HCydkqZ=y6o=Qt} zj=gaLwe;rQ)efCwuT`LSUMtWlwx+b_^2TkKH!2gkB_ACSnFAb~Knur`uP-#8O$k;k z<~Y92H+O)`A#j2Z!(sPqQxhmUE5{DI#2AGK6y{Uv>}-yQehT^w1e8L>vLwzA*k@V> z0)dzvaZWzS*e4$xbnN6C;s;&?4;6MoND&G%F3|4)!BcJs$;f=0?;w3qGLZSA)XL8_ zi~`c#DBrHYX;xwf7w7{qGL3d&WfsXUBp6Sk&m+O5q7o1(9(+Cx_|KwJ3DXfPuk6?TPq~T;r@2Ha8?cKL7{H6~wxB6=7+%mC0 zizIjXhrD#x%evLTyS>{j)f!5iy#zgi&9u7%38z%Yq1*~L0|Tx&ri%81s&|C3J0S=y zYG#F&t;m>O)*!4(6b2L&#Y!m3j6PW@X^>AU%6k>Hgb)HsX+=3(q=s24mbJ33C=`(u z-HQaRg7vJT7#JfiD2RZHXDWE)D|8eEaAbxEXba|$pqVjn=YK4G6$(W+eMREY%?~@m z(al^MWeV`;COh0FKG*@Qrr>eZ4IYPSbSfgntj+$VGqv~4698_eGQwM z{Oj z11*g6&N6F@cFY^awbRZRXl*@8#y?T7j^8H^KA$62LG-2I^kAL5+B7Ns17$3V9GY3{Q{VdVRqm+Af2145PNl* zscJA#fb{8hm_4b58z{6*bOcEjiD!tIadNGZ6!Q#`&)jg!x6f~GhG-vjWZ?31o5Nx9 zMrLvfdKovWGQ)SO)%Tb!Y~$oc>7CfG0R)5Y9oJvFo9etZva)keHM!^3#_EPW%SrpQ zklb^9#4Yhmy@6NrN>FiYW0NoxK>}m=ndMaHQmXTjf!piqt3!ud!hdN=9NrvfFZ~#O z8Q3s4hv198isUeoBS=mlIf|soKD>rJBpLW)#`$C6A=rm5ZWXZR8(4+3JEi=l>OL-H zgEfc)gIR+=!y*M+gRGez@r}+{-ZvmO*TOjOrfXC1TElCN zK%yxHwFcV)Xy>W4M2qK*6R4$!U0vQ zt6GDWi8Y_e!RUf^#s*&cW2_Q@(TXe{xs&W-NFQxo6j!k}g`8+j3!cV#ejP{7gP>pO|Fg$=8WE zZ=>^VBmXEM{}EWNOw*J@5mqbmjaI9DeYO50s}*=g1YJsx?^?a8a)+}6GJyNW(JyLB zj>Tsl-v*A2tjMHls#Zup|7hdjz~Io{fqi@T4WHaMaB%;?!GVFdCGZIly;m?MS)2h6 zNS&FzBU(xBC@2^3CkT)HQBiOJc~lfKkBf>9awjoSG$3Yas^x-)o`+E>nG_+=oe0Na zVDFjBI7s&+S9}y29R&!NLkI_5@L?e14U^-#CN5=0c|aDB+nq4)?FY~YLvfG%zUK?v z_k7`wIKS^}`gNbZq3ij0|1|q$i?o3QLpz-fmElnS0M>I&Sc$_+?utU!WW`~kvg1n{knTaPv00Kj*+o6`N&*?qKk>lhv;!A?Oa{Hbv0Di2^C z!{gMl$n_c?hRKmSXf-I~aJ9m5Mx5G`0=Ew*(Xyxrh&eG3?#%An4D zG%GX@1R#6d)YKWJILS~WJ&iSQBVpJRp&^YTc^8QS1VDBF*MVQ&TLbi^DmFfY1dnYx z31q&tAE9o40e|%Ehs0EaS}P22*h-*;!X&slOcO7R`dBDj!BJc&OsBCZAt?e00}rg_v8yM8{TuaW{JOmh@vB;W`D87duWmgB_;rViU$-&*y4;?vwPzRGcRLVP zT1>+=Pv24+E?*ixHPVNm)#f#pID3ioA!zj^d?i=nHvBxmlW0wj%L$7-rGTLTJkI8!H?Hg!ku z9c@dslzo8GJWn1c@1p>H1;WxQzVW1C1XLj$7M_H|` zwht|`IL*z>&g{<340mT&%c)d?K%4#MSy_t_@(c;Di5wA@?*np&D1;J4P(mk!;~^T# zARayurXqVsjz=xv9gk6o^@u0p#}hQ+N+oF$q#`F;j;Cmf@uDYMkIPifkWZ3h89q-C z_K;zhR1!*T3ppoxG)-?JJw%bV5G6hw;zG1-Dx6KuW=`prZDl4+nz7I7nUAS?PA>t2 z>XuofB|Y~X#j}Ew)C|M4HM?vY)+o^NliF0dbkZ!H$4*!8qq1c`6dcJLrX;u);VaDl zgyl_u+#%zBUy%&E_zsw9lt!T+2c3q&)l#Lb8@7c48Rytw(bB0kc+os(>!q{j%-XCr z_`YtPx6SGxoAkUrGg#4Wo9?a7*k?^+(8lj$P_4Qjm#fY=l1I=ajGTf$3&CgPkID91 zC+3rxIWe;g3{pbiHP?5-@&It|kWUB|Ai^O@+o%#|SVR$NbSjdKITCsq zo%6g66ies{uStLaEiC^%&JqTaMF}gS5`kf2ij<2EA}0=iAtjL$m1HiI7mA@VPe1Uk zG(0MdMFJfz>ZOAb9*4B$tr#9h3t00~!+ak<58H>r#BM^A79};#QXY9@EeM-iBlX^b zj)^Wp##=p!u?-&9c=wQT3^Hq8?7ca)Elt|!uoZ1J?H>wCN@-n}m0O$US=Gv7_!a9m zHfgPDT|*13YE|TQS@k-;YedYA__}=eiZ)m&2jaE*H;JAnlnps?FGSCXjCXi}321|V zR<<5ejCk7KTZbQxAr`}9xEQQxMsyrv!&@=xX&5mjWPVYUjvOPz{Dt?$kfA+I5!vQx zHr}xGrHk?Xg3@;S^8V1UyF@GP|Mj>)=JMv*>{0z0u-XzNX~s$0Fs8scg=LnNM4l zEy~tntLx#!Iy{{4#`4~-hg-Opt5?_XaHio|4+9TJ{v!`>``&pN*2b01kYOFYR*bPc z^>_M--@I0yijb$Hq2aBzsx8=C8+JpOjAbH?cwKQZmI2?r$Q!j^9Muo7H=} zzX=&uoDZi+wtLhOCp24oj@!B;p47_5bF8~+xMeN<>X)C*CWi7u!+Y}ucs%?7;Mu4X zDo;3~p-t;f%+|GO708G_ZJsMTi4xT{Tc1!h+ey@_Fag7#Z-zl1icZ9avc3WZu};;h zHl;f)r5dGBb8{+Q(JYQW46$0-Nq|(@U?+juVa!NM?kw@>y#D zIfbmXhcSk-RyJ|fNtCU!VcD8d(w!(AHEI=`;>wy8op5y~kD!2H2*Lh`!rww8BUxc~ z6vrC&rU7KdH2b_RK-?~vIp>x7iK{SoW`vt|C~G<4if&{hbSKPA`vBl<`w$ExI5aB< zzODe@;)q~Zp5iG0tl5Ls{F5m$5RJJGz*mRa40Mk>&4Jn0z~EpE&GAw9{)d1Cl-(xuh2g?sAHL26C!fA9`vsL|awW9GvW0^L3e!~Bh$VBn zs!^R{%}KG4q}u_2@uHfR~hg)Z>ch=0k+Sv|D);#3z zXXM+KwxuZP$}DF37JGLtcK0v#4Z-sw73(SrKoA32~y?b8H%}KeZa&AFtdg@Z{ z%UPe-OmX&8DR-|gC=sB1iLZADB|Pehl$%>^#>Mu{caPpaIwuW$Y27+HFZTj={{jPb zd0;_upLuCuPVV(djyypnpI2|9IQywIaO*%&!lOX-)=}OO92)TZ7kqgi0qI4#a%2L~9a%Y_BWeI7}LIk}&cj}eE7uxmcR2mAqeprOR^CsF|?x^m;noRql- z{svH&GYgXYJd!fkulN*4o&fKn&#N~m>~MwWaUfsDM;=QViuV#tS1WkQ!LC-mfsBW{ zIAM^umn(3+0#_-~fB!0lUD3o2hcaaKtC%tWdIM~5+nD5GjkhAUB$VlnC#olegxJKPEx{0!@_0N6&ixUKWs?VT(3vWSFxSt7WX zZ6fjX&D4$5J^Dbno~lc`7Sr4AcHQn;NbjnrcP*p~^>pFa1NHP<*Q2nw-8#pX>i+v< za}oepMHeLZc_j6-#S+QK0el_>eJLLSHjX!W#QPa@zc3NdMnW{PoRh>2`Y84&u7FE4a z(<)f40VS*IWSLrarEKVisjBoN9P<1<958HJK2w9pfxwSZ0M}#|Pl^i= z1Gpww$p1O{OK5AP`{j`hkzOu{GFh=)teu;_CmE5lD_EtS?9cvUJeOD_i~to+LjP|DdmLTKNA4VkN*JS C%;gOL diff --git a/tests/__pycache__/test_templates.cpython-313-pytest-9.0.3.pyc b/tests/__pycache__/test_templates.cpython-313-pytest-9.0.3.pyc deleted file mode 100644 index 14c43a74cf0fb95888225ab4a229c215c0bf22c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30449 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 diff --git a/tests/__pycache__/test_types.cpython-313-pytest-9.0.3.pyc b/tests/__pycache__/test_types.cpython-313-pytest-9.0.3.pyc deleted file mode 100644 index 46027cf08141b2ad18aa3264bb6cc145f064ff2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14917 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 Q1((-#!u8(*QZ_997aV6z00000