From a0388d178b5a793836e0aab124ff226584c546a3 Mon Sep 17 00:00:00 2001 From: gabino Date: Mon, 27 Jan 2025 13:31:50 -0600 Subject: [PATCH 1/7] Replace HttpUrl with HttpUrlString from cuenca-validations --- cuenca/resources/endpoints.py | 9 +++++---- cuenca/resources/files.py | 4 ++-- cuenca/resources/sessions.py | 7 ++++--- cuenca/resources/users.py | 5 +++-- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/cuenca/resources/endpoints.py b/cuenca/resources/endpoints.py index 7d6b1b69..c0231092 100644 --- a/cuenca/resources/endpoints.py +++ b/cuenca/resources/endpoints.py @@ -1,11 +1,12 @@ from typing import ClassVar, Optional from cuenca_validations.types.enums import WebhookEvent +from cuenca_validations.types.general import HttpUrlString from cuenca_validations.types.requests import ( EndpointRequest, EndpointUpdateRequest, ) -from pydantic import ConfigDict, Field, HttpUrl +from pydantic import ConfigDict, Field from ..http import Session, session as global_session from .base import Creatable, Deactivable, Queryable, Retrievable, Updateable @@ -14,7 +15,7 @@ class Endpoint(Creatable, Deactivable, Retrievable, Queryable, Updateable): _resource: ClassVar = 'endpoints' - url: HttpUrl = Field(description='HTTPS url to send webhooks') + url: HttpUrlString = Field(description='HTTPS url to send webhooks') secret: str = Field( description='token to verify the webhook is sent by Cuenca ' 'using HMAC algorithm', @@ -51,7 +52,7 @@ class Endpoint(Creatable, Deactivable, Retrievable, Queryable, Updateable): @classmethod def create( cls, - url: HttpUrl, + url: HttpUrlString, events: Optional[list[WebhookEvent]] = None, *, session: Session = global_session, @@ -72,7 +73,7 @@ def create( def update( cls, endpoint_id: str, - url: Optional[HttpUrl] = None, + url: Optional[HttpUrlString] = None, events: Optional[list[WebhookEvent]] = None, is_enable: Optional[bool] = None, *, diff --git a/cuenca/resources/files.py b/cuenca/resources/files.py index f97fbf93..87990c48 100644 --- a/cuenca/resources/files.py +++ b/cuenca/resources/files.py @@ -2,7 +2,7 @@ from typing import ClassVar, Optional from cuenca_validations.types import FileQuery, FileUploadRequest, KYCFileType -from pydantic import HttpUrl +from cuenca_validations.types.general import HttpUrlString from ..http import Session, session as global_session from .base import Downloadable, Queryable, Uploadable @@ -14,7 +14,7 @@ class File(Downloadable, Queryable, Uploadable): extension: str type: KYCFileType - url: HttpUrl + url: HttpUrlString user_id: str @classmethod diff --git a/cuenca/resources/sessions.py b/cuenca/resources/sessions.py index 4c8eff0d..72527585 100644 --- a/cuenca/resources/sessions.py +++ b/cuenca/resources/sessions.py @@ -2,7 +2,8 @@ from typing import ClassVar, Optional from cuenca_validations.types import SessionRequest, SessionType -from pydantic import AnyUrl, ConfigDict +from cuenca_validations.types.general import AnyUrlString +from pydantic import ConfigDict from .. import http from .base import Creatable, Queryable, Retrievable @@ -16,8 +17,8 @@ class Session(Creatable, Retrievable, Queryable): user_id: str platform_id: str expires_at: dt.datetime - success_url: Optional[AnyUrl] = None - failure_url: Optional[AnyUrl] = None + success_url: Optional[AnyUrlString] = None + failure_url: Optional[AnyUrlString] = None type: Optional[SessionType] = None model_config = ConfigDict( diff --git a/cuenca/resources/users.py b/cuenca/resources/users.py index 19798589..99629357 100644 --- a/cuenca/resources/users.py +++ b/cuenca/resources/users.py @@ -15,8 +15,9 @@ UserUpdateRequest, ) from cuenca_validations.types.enums import Country, Gender, State +from cuenca_validations.types.general import HttpUrlString from cuenca_validations.types.identities import Curp -from pydantic import ConfigDict, EmailStr, Field, HttpUrl +from pydantic import ConfigDict, EmailStr, Field from ..http import Session, session as global_session from .balance_entries import BalanceEntry @@ -147,7 +148,7 @@ def update( status: Optional[UserStatus] = None, email_verification_id: Optional[str] = None, phone_verification_id: Optional[str] = None, - curp_document: Optional[HttpUrl] = None, + curp_document: Optional[HttpUrlString] = None, *, session: Session = global_session, ) -> 'User': From eec63878a7fcd636a8b24721973be975269bc36c Mon Sep 17 00:00:00 2001 From: gabino Date: Mon, 27 Jan 2025 13:51:39 -0600 Subject: [PATCH 2/7] Handle SecretStr for password in UserCredential methods --- cuenca/resources/user_credentials.py | 11 +++++++++-- tests/resources/cassettes/test_update_password.yaml | 6 +++--- tests/resources/test_user_credentials.py | 6 +++--- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/cuenca/resources/user_credentials.py b/cuenca/resources/user_credentials.py index cde0bd39..764c9437 100644 --- a/cuenca/resources/user_credentials.py +++ b/cuenca/resources/user_credentials.py @@ -5,6 +5,7 @@ UserCredentialRequest, UserCredentialUpdateRequest, ) +from pydantic import SecretStr from ..http import Session, session as global_session from .base import Creatable, Updateable @@ -25,7 +26,10 @@ def create( session: Session = global_session, ) -> 'UserCredential': req = UserCredentialRequest(password=password, user_id=user_id) - return cls._create(**req.model_dump(), session=session) + data = req.model_dump() + if isinstance(data['password'], SecretStr): + data['password'] = data['password'].get_secret_value() + return cls._create(**data, session=session) @classmethod def update( @@ -40,4 +44,7 @@ def update( is_active=is_active, password=password, ) - return cls._update(id=user_id, **req.model_dump(), session=session) + data = req.model_dump() + if password and isinstance(data['password'], SecretStr): + data['password'] = data['password'].get_secret_value() + return cls._update(id=user_id, **data, session=session) diff --git a/tests/resources/cassettes/test_update_password.yaml b/tests/resources/cassettes/test_update_password.yaml index 17bd3ffa..358a3965 100644 --- a/tests/resources/cassettes/test_update_password.yaml +++ b/tests/resources/cassettes/test_update_password.yaml @@ -1,6 +1,6 @@ interactions: - request: - body: '{"password": "222222"}' + body: '{"password": "22222222"}' headers: Accept: - '*/*' @@ -54,7 +54,7 @@ interactions: code: 201 message: Created - request: - body: '{"password": "222222"}' + body: '{"password": "22222222"}' headers: Accept: - '*/*' @@ -108,7 +108,7 @@ interactions: code: 201 message: Created - request: - body: '{"is_active": null, "password": "111111"}' + body: '{"is_active": null, "password": "11111111"}' headers: Accept: - '*/*' diff --git a/tests/resources/test_user_credentials.py b/tests/resources/test_user_credentials.py index c9cec4f5..5e0ba458 100644 --- a/tests/resources/test_user_credentials.py +++ b/tests/resources/test_user_credentials.py @@ -7,9 +7,9 @@ @pytest.mark.vcr def test_update_password(): - UserCredential.create('222222') - UserLogin.create('222222') - UserCredential.update(password='111111') + UserCredential.create('22222222') + UserLogin.create('22222222') + UserCredential.update(password='11111111') @pytest.mark.vcr From f1947e4399b69c23b8bf6712868bbbb8645b2df2 Mon Sep 17 00:00:00 2001 From: gabino Date: Mon, 27 Jan 2025 15:41:12 -0600 Subject: [PATCH 3/7] Bump cuenca-validations to version 2.0.4 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 372eb38d..3568110f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ requests==2.32.3 -cuenca-validations==2.0.0 +cuenca-validations==2.0.4 pydantic-extra-types==2.10.2 From e9325accd355db6abc735a8caa6830fd428435a6 Mon Sep 17 00:00:00 2001 From: gabino Date: Mon, 27 Jan 2025 16:00:57 -0600 Subject: [PATCH 4/7] Update URL type to SerializableHttpUrl and SerializableAnyUrl --- cuenca/resources/endpoints.py | 8 ++++---- cuenca/resources/files.py | 4 ++-- cuenca/resources/sessions.py | 6 +++--- cuenca/resources/users.py | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/cuenca/resources/endpoints.py b/cuenca/resources/endpoints.py index c0231092..762b28ba 100644 --- a/cuenca/resources/endpoints.py +++ b/cuenca/resources/endpoints.py @@ -1,7 +1,7 @@ from typing import ClassVar, Optional from cuenca_validations.types.enums import WebhookEvent -from cuenca_validations.types.general import HttpUrlString +from cuenca_validations.types.general import SerializableHttpUrl from cuenca_validations.types.requests import ( EndpointRequest, EndpointUpdateRequest, @@ -15,7 +15,7 @@ class Endpoint(Creatable, Deactivable, Retrievable, Queryable, Updateable): _resource: ClassVar = 'endpoints' - url: HttpUrlString = Field(description='HTTPS url to send webhooks') + url: SerializableHttpUrl = Field(description='HTTPS url to send webhooks') secret: str = Field( description='token to verify the webhook is sent by Cuenca ' 'using HMAC algorithm', @@ -52,7 +52,7 @@ class Endpoint(Creatable, Deactivable, Retrievable, Queryable, Updateable): @classmethod def create( cls, - url: HttpUrlString, + url: SerializableHttpUrl, events: Optional[list[WebhookEvent]] = None, *, session: Session = global_session, @@ -73,7 +73,7 @@ def create( def update( cls, endpoint_id: str, - url: Optional[HttpUrlString] = None, + url: Optional[SerializableHttpUrl] = None, events: Optional[list[WebhookEvent]] = None, is_enable: Optional[bool] = None, *, diff --git a/cuenca/resources/files.py b/cuenca/resources/files.py index 87990c48..83c5311e 100644 --- a/cuenca/resources/files.py +++ b/cuenca/resources/files.py @@ -2,7 +2,7 @@ from typing import ClassVar, Optional from cuenca_validations.types import FileQuery, FileUploadRequest, KYCFileType -from cuenca_validations.types.general import HttpUrlString +from cuenca_validations.types.general import SerializableHttpUrl from ..http import Session, session as global_session from .base import Downloadable, Queryable, Uploadable @@ -14,7 +14,7 @@ class File(Downloadable, Queryable, Uploadable): extension: str type: KYCFileType - url: HttpUrlString + url: SerializableHttpUrl user_id: str @classmethod diff --git a/cuenca/resources/sessions.py b/cuenca/resources/sessions.py index 72527585..f08caa88 100644 --- a/cuenca/resources/sessions.py +++ b/cuenca/resources/sessions.py @@ -2,7 +2,7 @@ from typing import ClassVar, Optional from cuenca_validations.types import SessionRequest, SessionType -from cuenca_validations.types.general import AnyUrlString +from cuenca_validations.types.general import SerializableAnyUrl from pydantic import ConfigDict from .. import http @@ -17,8 +17,8 @@ class Session(Creatable, Retrievable, Queryable): user_id: str platform_id: str expires_at: dt.datetime - success_url: Optional[AnyUrlString] = None - failure_url: Optional[AnyUrlString] = None + success_url: Optional[SerializableAnyUrl] = None + failure_url: Optional[SerializableAnyUrl] = None type: Optional[SessionType] = None model_config = ConfigDict( diff --git a/cuenca/resources/users.py b/cuenca/resources/users.py index 99629357..e6efbe68 100644 --- a/cuenca/resources/users.py +++ b/cuenca/resources/users.py @@ -15,7 +15,7 @@ UserUpdateRequest, ) from cuenca_validations.types.enums import Country, Gender, State -from cuenca_validations.types.general import HttpUrlString +from cuenca_validations.types.general import SerializableHttpUrl from cuenca_validations.types.identities import Curp from pydantic import ConfigDict, EmailStr, Field @@ -148,7 +148,7 @@ def update( status: Optional[UserStatus] = None, email_verification_id: Optional[str] = None, phone_verification_id: Optional[str] = None, - curp_document: Optional[HttpUrlString] = None, + curp_document: Optional[SerializableHttpUrl] = None, *, session: Session = global_session, ) -> 'User': From 93d1deec68b359666f99d914ce06c27f76e92bcd Mon Sep 17 00:00:00 2001 From: gabino Date: Mon, 27 Jan 2025 16:01:34 -0600 Subject: [PATCH 5/7] Bump cuenca-validations to version 2.0.4 in setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 38e57211..2d847811 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ python_requires='>=3.9', install_requires=[ 'requests>=2.32.0', - 'cuenca-validations>=2.0.0', + 'cuenca-validations>=2.0.4', 'pydantic-extra-types>=2.10.0', ], classifiers=[ From 14c4f2f33b954c015530624e33e5f22c1cb85074 Mon Sep 17 00:00:00 2001 From: gabino Date: Mon, 27 Jan 2025 16:01:48 -0600 Subject: [PATCH 6/7] Bump version to 2.0.1 --- cuenca/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cuenca/version.py b/cuenca/version.py index b7fc5d71..68b04b6a 100644 --- a/cuenca/version.py +++ b/cuenca/version.py @@ -1,3 +1,3 @@ -__version__ = '2.0.0' +__version__ = '2.0.1' CLIENT_VERSION = __version__ API_VERSION = '2020-03-19' From 4b82c7d08c372151f9f5a1c068b4c2234a4c21c1 Mon Sep 17 00:00:00 2001 From: gabino Date: Mon, 27 Jan 2025 18:17:39 -0600 Subject: [PATCH 7/7] Simplify SecretStr handling in UserCredential methods --- cuenca/resources/user_credentials.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cuenca/resources/user_credentials.py b/cuenca/resources/user_credentials.py index 764c9437..1444b84f 100644 --- a/cuenca/resources/user_credentials.py +++ b/cuenca/resources/user_credentials.py @@ -5,7 +5,6 @@ UserCredentialRequest, UserCredentialUpdateRequest, ) -from pydantic import SecretStr from ..http import Session, session as global_session from .base import Creatable, Updateable @@ -27,8 +26,7 @@ def create( ) -> 'UserCredential': req = UserCredentialRequest(password=password, user_id=user_id) data = req.model_dump() - if isinstance(data['password'], SecretStr): - data['password'] = data['password'].get_secret_value() + data['password'] = data['password'].get_secret_value() return cls._create(**data, session=session) @classmethod @@ -45,6 +43,6 @@ def update( password=password, ) data = req.model_dump() - if password and isinstance(data['password'], SecretStr): + if password: data['password'] = data['password'].get_secret_value() return cls._update(id=user_id, **data, session=session)