From 67d08a849a516acb3568ab26cb685e8bfc0010c9 Mon Sep 17 00:00:00 2001 From: Reza Tabrizi <63474681+rezabrizi@users.noreply.github.com> Date: Wed, 11 Jun 2025 13:11:03 -0500 Subject: [PATCH 01/12] execute products and subscriptions on connect, support 'expand' without [] --- method/configuration.py | 4 +- method/resource.py | 15 ++++- method/resources/Entities/Connect.py | 65 ++++++++++++++++++---- method/resources/Entities/Subscriptions.py | 4 +- test.py | 34 +++++++++++ 5 files changed, 104 insertions(+), 18 deletions(-) create mode 100644 test.py diff --git a/method/configuration.py b/method/configuration.py index bc6f7bb..01cb0b5 100644 --- a/method/configuration.py +++ b/method/configuration.py @@ -26,8 +26,8 @@ class Configuration: env: EnvironmentLiterals def __init__(self, opts: ConfigurationOpts): - url = 'https://{env}.methodfi.com' - + # url = 'https://{env}.methodfi.com' + url = 'http://localhost:8081' self.__validate(opts) self.api_key = opts.get('api_key', '') self.url = url.format(env=opts.get('env', 'dev')) diff --git a/method/resource.py b/method/resource.py index 045f76b..e983ee9 100644 --- a/method/resource.py +++ b/method/resource.py @@ -160,8 +160,17 @@ def _make_request(self, method: str, path: Optional[str] = None, data: Optional[ options = {} if data: options['data'] = json.dumps(data) + # Note (Reza): Automatically appends '[]' to list-type query params (e.g., 'expand') + # so users can pass them naturally without needing to format keys manually. if params: - options['params'] = params + fixed = {} + for k, v in params.items(): + if isinstance(v, list): + fixed[f"{k}[]"] = v + else: + fixed[k] = v + options['params'] = fixed + if headers: options['headers'] = headers @@ -211,11 +220,11 @@ def _list(self, params: Optional[Dict] = None) -> MethodResponse[List[T]]: return self._make_request('GET', params=params) @MethodError.catch - def _create(self, data: Dict, request_opts: Optional[RequestOpts] = None) -> MethodResponse[T]: + def _create(self, data: Dict, params: Optional[Dict] = None, request_opts: Optional[RequestOpts] = None) -> MethodResponse[T]: headers = {} if request_opts and request_opts.get('idempotency_key'): headers['Idempotency-Key'] = request_opts.get('idempotency_key') - return self._make_request('POST', data=data, headers=headers) + return self._make_request('POST', data=data, headers=headers, params=params) @MethodError.catch def _create_with_sub_path(self, path: str, data: Dict) -> MethodResponse[T]: diff --git a/method/resources/Entities/Connect.py b/method/resources/Entities/Connect.py index 9cdb9d2..f894506 100644 --- a/method/resources/Entities/Connect.py +++ b/method/resources/Entities/Connect.py @@ -6,10 +6,33 @@ EntityConnectResponseStatusLiterals = Literal[ - 'completed', - 'in_progress', - 'pending', - 'failed' + "completed", "in_progress", "pending", "failed" +] + +AccountConnectResponseExpandLiterals = Literal[ + "accounts", + "accounts.sensitive", + "accounts.balance", + "accounts.card_brand", + "accounts.attribute", + "accounts.payoff", + "accounts.transaction", + "accounts.update", + "accounts.payment_instrument", + "accounts.latest_verification_session", +] + +AccountProductsEligibleForAutomaticExecutionLiteral = Literal[ + "account_attribute", + "balance", + "card_brand", + "update", + "payoff", +] + + +AccountSubscriptionsEligibleForAutomaticExecutionLiteral = Literal[ + "card_brand", "update", "update.snapshot", "transaction" ] @@ -22,15 +45,35 @@ class EntityConnect(TypedDict): updated_at: str +class ConnectExpandOpts(TypedDict): + expand: AccountConnectResponseExpandLiterals + + +class ConnectResourceListOpts(ResourceListOpts, ConnectExpandOpts): + pass + class EntityConnectResource(Resource): def __init__(self, config: Configuration): - super(EntityConnectResource, self).__init__(config.add_path('connect')) + super(EntityConnectResource, self).__init__(config.add_path("connect")) + + def retrieve(self, cxn_id: str, params: Optional[ConnectExpandOpts] = None) -> MethodResponse[EntityConnect]: + return super(EntityConnectResource, self)._get_with_sub_path_and_params(cxn_id, params=params) - def retrieve(self, cxn_id: str) -> MethodResponse[EntityConnect]: - return super(EntityConnectResource, self)._get_with_id(cxn_id) - - def list(self, params: Optional[ResourceListOpts] = None) -> MethodResponse[List[EntityConnect]]: + def list( + self, params: Optional[ConnectResourceListOpts] = None + ) -> MethodResponse[List[EntityConnect]]: return super(EntityConnectResource, self)._list(params) - def create(self) -> MethodResponse[EntityConnect]: - return super(EntityConnectResource, self)._create({}) + def create( + self, + products: Optional[List[AccountProductsEligibleForAutomaticExecutionLiteral]] = None, + subscriptions: Optional[List[AccountSubscriptionsEligibleForAutomaticExecutionLiteral]] = None, + params: Optional[ConnectExpandOpts] = None + ) -> MethodResponse[EntityConnect]: + data = {} + if products: + data["products"] = products + if subscriptions: + data["subscriptions"] = subscriptions + return super(EntityConnectResource, self)._create(data=data, params=params) + \ No newline at end of file diff --git a/method/resources/Entities/Subscriptions.py b/method/resources/Entities/Subscriptions.py index 76ee8bc..d640632 100644 --- a/method/resources/Entities/Subscriptions.py +++ b/method/resources/Entities/Subscriptions.py @@ -1,4 +1,4 @@ -from typing import TypedDict, Optional, Literal, Dict, Any +from typing import TypedDict, Optional, Literal, Dict, Any, Union from method.resource import MethodResponse, Resource from method.configuration import Configuration @@ -54,7 +54,7 @@ def retrieve(self, sub_id: str) -> MethodResponse[EntitySubscriptionResponseOpts def list(self) -> MethodResponse[EntitySubscriptionListResponse]: return super(EntitySubscriptionsResource, self)._list() - def create(self, opts: EntitySubscriptionCreateOpts | EntitySubscriptionNamesLiterals) -> MethodResponse[EntitySubscriptionResponseOpts]: + def create(self, opts: Union[EntitySubscriptionCreateOpts, EntitySubscriptionNamesLiterals]) -> MethodResponse[EntitySubscriptionResponseOpts]: if isinstance(opts, str): opts = {'enroll': opts} return super(EntitySubscriptionsResource, self)._create(opts) diff --git a/test.py b/test.py new file mode 100644 index 0000000..90d736f --- /dev/null +++ b/test.py @@ -0,0 +1,34 @@ +from method import Method + +method = Method({"api_key":"sk_R6PLdTR9gPnBH9hqHVGnzbD9", "env" : "dev"}) + +Entity = method.entities.create( + opts={ + "type": "individual", + "individual": { + "first_name": "John", + "last_name": "Doe", + "phone": "+15121231123", + "dob": "1997-03-18", + "email": "john_doe@gmail.com" + }, + "address": { + "line1": "3300 N Interstate 35", + "line2": None, + "city": "Austin", + "state": "TX", + "zip": "78705" + } +} +) + +# print(Entity) +cxn = method.entities(Entity["id"]).connect.create(products=["balance", "card_brand"], params={"expand": ["accounts"]}) +cxn_get = method.entities(Entity["id"]).connect.retrieve(cxn["id"], params={"expand": ["accounts"]}) +cxn_list = method.entities(Entity["id"]).connect.list(params={"expand": ["accounts"]}) + + +# account_expanded = method.accounts.retrieve("acc_yL8VxnkUJg33f", {"expand": ["update"]}) + +import json +print(json.dumps(dict(cxn_list[0]), indent=2)) From 7b5de4c0b9cab28858bc00b6c29cbb350043010a Mon Sep 17 00:00:00 2001 From: Reza Tabrizi <63474681+rezabrizi@users.noreply.github.com> Date: Wed, 11 Jun 2025 13:15:47 -0500 Subject: [PATCH 02/12] minor fix --- method/configuration.py | 4 ++-- test.py | 34 ---------------------------------- 2 files changed, 2 insertions(+), 36 deletions(-) delete mode 100644 test.py diff --git a/method/configuration.py b/method/configuration.py index 01cb0b5..4fda606 100644 --- a/method/configuration.py +++ b/method/configuration.py @@ -26,8 +26,8 @@ class Configuration: env: EnvironmentLiterals def __init__(self, opts: ConfigurationOpts): - # url = 'https://{env}.methodfi.com' - url = 'http://localhost:8081' + url = 'https://{env}.methodfi.com' + self.__validate(opts) self.api_key = opts.get('api_key', '') self.url = url.format(env=opts.get('env', 'dev')) diff --git a/test.py b/test.py deleted file mode 100644 index 90d736f..0000000 --- a/test.py +++ /dev/null @@ -1,34 +0,0 @@ -from method import Method - -method = Method({"api_key":"sk_R6PLdTR9gPnBH9hqHVGnzbD9", "env" : "dev"}) - -Entity = method.entities.create( - opts={ - "type": "individual", - "individual": { - "first_name": "John", - "last_name": "Doe", - "phone": "+15121231123", - "dob": "1997-03-18", - "email": "john_doe@gmail.com" - }, - "address": { - "line1": "3300 N Interstate 35", - "line2": None, - "city": "Austin", - "state": "TX", - "zip": "78705" - } -} -) - -# print(Entity) -cxn = method.entities(Entity["id"]).connect.create(products=["balance", "card_brand"], params={"expand": ["accounts"]}) -cxn_get = method.entities(Entity["id"]).connect.retrieve(cxn["id"], params={"expand": ["accounts"]}) -cxn_list = method.entities(Entity["id"]).connect.list(params={"expand": ["accounts"]}) - - -# account_expanded = method.accounts.retrieve("acc_yL8VxnkUJg33f", {"expand": ["update"]}) - -import json -print(json.dumps(dict(cxn_list[0]), indent=2)) From 8980707119551c2cbf280c31b511dc06caf07dfd Mon Sep 17 00:00:00 2001 From: Reza Tabrizi <63474681+rezabrizi@users.noreply.github.com> Date: Wed, 11 Jun 2025 13:18:49 -0500 Subject: [PATCH 03/12] formatting fix --- method/configuration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/method/configuration.py b/method/configuration.py index 4fda606..bc6f7bb 100644 --- a/method/configuration.py +++ b/method/configuration.py @@ -27,7 +27,7 @@ class Configuration: def __init__(self, opts: ConfigurationOpts): url = 'https://{env}.methodfi.com' - + self.__validate(opts) self.api_key = opts.get('api_key', '') self.url = url.format(env=opts.get('env', 'dev')) From 791a9df85576fa22182e8d11ba159d1a85d96a6e Mon Sep 17 00:00:00 2001 From: Reza Tabrizi <63474681+rezabrizi@users.noreply.github.com> Date: Wed, 11 Jun 2025 13:34:13 -0500 Subject: [PATCH 04/12] fix tests --- test/resources/Account_test.py | 6 +++--- test/resources/Report_test.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/resources/Account_test.py b/test/resources/Account_test.py index 7a2c8d8..043e1f4 100644 --- a/test/resources/Account_test.py +++ b/test/resources/Account_test.py @@ -300,7 +300,7 @@ def test_create_card_brands(setup): 'id': card_brand_create_response['id'], 'account_id': test_credit_card_account['id'], 'network': 'visa', - 'status': 'completed', + 'status': 'in_progress', 'issuer': card_brand_create_response['issuer'], 'last4': '1580', 'brands': card_brand_create_response['brands'], @@ -322,7 +322,7 @@ def test_retrieve_card_brands(setup): 'id': card_brand_create_response['id'], 'account_id': test_credit_card_account['id'], 'network': 'visa', - 'status': 'completed', + 'status': 'in_progress', 'issuer': card_brand_create_response['issuer'], 'last4': '1580', 'brands': card_brand_create_response['brands'], @@ -345,7 +345,7 @@ async def test_list_card_brands(setup): 'id': card_brand_create_response['id'], 'account_id': test_credit_card_account['id'], 'network': 'visa', - 'status': 'completed', + 'status': 'in_progress', 'issuer': card_brand_create_response['issuer'], 'last4': '1580', 'brands': card_brand_create_response['brands'], diff --git a/test/resources/Report_test.py b/test/resources/Report_test.py index 939dab1..e9269cc 100644 --- a/test/resources/Report_test.py +++ b/test/resources/Report_test.py @@ -25,7 +25,7 @@ def test_create_report(): "type": "payments.created.current", "url": f"https://dev.methodfi.com/reports/{report_create_response['id']}/download", "status": "completed", - "metadata": None, + "metadata": report_create_response["metadata"], "created_at": report_create_response["created_at"], "updated_at": report_create_response["updated_at"], } @@ -43,7 +43,7 @@ def test_retrieve_report(): "type": "payments.created.current", "url": f"https://dev.methodfi.com/reports/{report_create_response['id']}/download", "status": "completed", - "metadata": None, + "metadata": report_create_response["metadata"], "created_at": report_retrieve_response["created_at"], "updated_at": report_retrieve_response["updated_at"], } From 687c74fba57d76edba93e62acefa36eb0ac9495b Mon Sep 17 00:00:00 2001 From: Reza Tabrizi <63474681+rezabrizi@users.noreply.github.com> Date: Wed, 11 Jun 2025 13:54:00 -0500 Subject: [PATCH 05/12] Fix card brand tests --- test/resources/Account_test.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/test/resources/Account_test.py b/test/resources/Account_test.py index 043e1f4..cf080a8 100644 --- a/test/resources/Account_test.py +++ b/test/resources/Account_test.py @@ -322,12 +322,16 @@ def test_retrieve_card_brands(setup): 'id': card_brand_create_response['id'], 'account_id': test_credit_card_account['id'], 'network': 'visa', - 'status': 'in_progress', + 'status': 'completed', 'issuer': card_brand_create_response['issuer'], 'last4': '1580', - 'brands': card_brand_create_response['brands'], + 'brands': [{ + + 'art_id': 'art_pCc787cy3ciWp', + + 'id': 'brand_UBwVzXjpP4PJ6', + + 'name': 'Chase Sapphire Reserve', + + 'url': 'https://static.methodfi.com/card_brands/1b7ccaba6535cb837f802d968add4700.png'}], 'shared': False, - 'source': card_brand_create_response['source'], + 'source': "network", 'error': None, 'created_at': card_retrieve_response['created_at'], 'updated_at': card_retrieve_response['updated_at'], @@ -345,12 +349,16 @@ async def test_list_card_brands(setup): 'id': card_brand_create_response['id'], 'account_id': test_credit_card_account['id'], 'network': 'visa', - 'status': 'in_progress', + 'status': 'completed', 'issuer': card_brand_create_response['issuer'], 'last4': '1580', - 'brands': card_brand_create_response['brands'], + 'brands': [{ + + 'art_id': 'art_pCc787cy3ciWp', + + 'id': 'brand_UBwVzXjpP4PJ6', + + 'name': 'Chase Sapphire Reserve', + + 'url': 'https://static.methodfi.com/card_brands/1b7ccaba6535cb837f802d968add4700.png'}], 'shared': False, - 'source': card_brand_create_response['source'], + 'source': "network" 'error': None, 'created_at': card_brands_list_response[0]['created_at'], 'updated_at': card_brands_list_response[0]['updated_at'], From b1c2a4c529f76b70f926913ca4e0d040a9fa0b41 Mon Sep 17 00:00:00 2001 From: Reza Tabrizi <63474681+rezabrizi@users.noreply.github.com> Date: Wed, 11 Jun 2025 13:55:41 -0500 Subject: [PATCH 06/12] minor fix --- test/resources/Account_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/resources/Account_test.py b/test/resources/Account_test.py index cf080a8..29eaba5 100644 --- a/test/resources/Account_test.py +++ b/test/resources/Account_test.py @@ -358,7 +358,7 @@ async def test_list_card_brands(setup): + 'name': 'Chase Sapphire Reserve', + 'url': 'https://static.methodfi.com/card_brands/1b7ccaba6535cb837f802d968add4700.png'}], 'shared': False, - 'source': "network" + 'source': "network", 'error': None, 'created_at': card_brands_list_response[0]['created_at'], 'updated_at': card_brands_list_response[0]['updated_at'], From f5ce5cb910a3149521b0862f05a1e56f3e1bd461 Mon Sep 17 00:00:00 2001 From: Reza Tabrizi <63474681+rezabrizi@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:01:42 -0500 Subject: [PATCH 07/12] change param name to opts --- method/resources/Entities/Connect.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/method/resources/Entities/Connect.py b/method/resources/Entities/Connect.py index f894506..94bb92e 100644 --- a/method/resources/Entities/Connect.py +++ b/method/resources/Entities/Connect.py @@ -56,24 +56,24 @@ class EntityConnectResource(Resource): def __init__(self, config: Configuration): super(EntityConnectResource, self).__init__(config.add_path("connect")) - def retrieve(self, cxn_id: str, params: Optional[ConnectExpandOpts] = None) -> MethodResponse[EntityConnect]: - return super(EntityConnectResource, self)._get_with_sub_path_and_params(cxn_id, params=params) + def retrieve(self, cxn_id: str, opts: Optional[ConnectExpandOpts] = None) -> MethodResponse[EntityConnect]: + return super(EntityConnectResource, self)._get_with_sub_path_and_params(cxn_id, params=opts) def list( - self, params: Optional[ConnectResourceListOpts] = None + self, opts: Optional[ConnectResourceListOpts] = None ) -> MethodResponse[List[EntityConnect]]: - return super(EntityConnectResource, self)._list(params) + return super(EntityConnectResource, self)._list(opts) def create( self, products: Optional[List[AccountProductsEligibleForAutomaticExecutionLiteral]] = None, subscriptions: Optional[List[AccountSubscriptionsEligibleForAutomaticExecutionLiteral]] = None, - params: Optional[ConnectExpandOpts] = None + opts: Optional[ConnectExpandOpts] = None ) -> MethodResponse[EntityConnect]: data = {} if products: data["products"] = products if subscriptions: data["subscriptions"] = subscriptions - return super(EntityConnectResource, self)._create(data=data, params=params) + return super(EntityConnectResource, self)._create(data=data, params=opts) \ No newline at end of file From 28e8d1a99116f92492b00e733f8f7188b7b79bc4 Mon Sep 17 00:00:00 2001 From: Reza Tabrizi <63474681+rezabrizi@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:07:13 -0500 Subject: [PATCH 08/12] formatting fix --- test/resources/Account_test.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/resources/Account_test.py b/test/resources/Account_test.py index 29eaba5..3137d9f 100644 --- a/test/resources/Account_test.py +++ b/test/resources/Account_test.py @@ -326,10 +326,10 @@ def test_retrieve_card_brands(setup): 'issuer': card_brand_create_response['issuer'], 'last4': '1580', 'brands': [{ - + 'art_id': 'art_pCc787cy3ciWp', - + 'id': 'brand_UBwVzXjpP4PJ6', - + 'name': 'Chase Sapphire Reserve', - + 'url': 'https://static.methodfi.com/card_brands/1b7ccaba6535cb837f802d968add4700.png'}], + 'art_id': 'art_pCc787cy3ciWp', + 'id': 'brand_UBwVzXjpP4PJ6', + 'name': 'Chase Sapphire Reserve', + 'url': 'https://static.methodfi.com/card_brands/1b7ccaba6535cb837f802d968add4700.png'}], 'shared': False, 'source': "network", 'error': None, @@ -353,10 +353,10 @@ async def test_list_card_brands(setup): 'issuer': card_brand_create_response['issuer'], 'last4': '1580', 'brands': [{ - + 'art_id': 'art_pCc787cy3ciWp', - + 'id': 'brand_UBwVzXjpP4PJ6', - + 'name': 'Chase Sapphire Reserve', - + 'url': 'https://static.methodfi.com/card_brands/1b7ccaba6535cb837f802d968add4700.png'}], + 'art_id': 'art_pCc787cy3ciWp', + 'id': 'brand_UBwVzXjpP4PJ6', + 'name': 'Chase Sapphire Reserve', + 'url': 'https://static.methodfi.com/card_brands/1b7ccaba6535cb837f802d968add4700.png'}], 'shared': False, 'source': "network", 'error': None, From 2b62c7099472c55110e99144c22defee9386ec66 Mon Sep 17 00:00:00 2001 From: Reza Tabrizi <63474681+rezabrizi@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:18:58 -0500 Subject: [PATCH 09/12] sleep for card brands --- test/resources/Account_test.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/resources/Account_test.py b/test/resources/Account_test.py index 3137d9f..3c8d604 100644 --- a/test/resources/Account_test.py +++ b/test/resources/Account_test.py @@ -1,6 +1,7 @@ import os from typing import List import pytest +import time from method import Method from dotenv import load_dotenv from utils import await_results @@ -311,13 +312,14 @@ def test_create_card_brands(setup): 'updated_at': card_brand_create_response['updated_at'], } + time.sleep(5) assert card_brand_create_response == expect_results def test_retrieve_card_brands(setup): test_credit_card_account = setup['test_credit_card_account'] + card_retrieve_response = method.accounts(test_credit_card_account['id']).card_brands.retrieve(card_brand_create_response['id']) - expect_results: AccountCardBrand = { 'id': card_brand_create_response['id'], 'account_id': test_credit_card_account['id'], From 148d9a2a2dec52311bb3238755af72ffaccca940 Mon Sep 17 00:00:00 2001 From: Reza Tabrizi <63474681+rezabrizi@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:27:42 -0500 Subject: [PATCH 10/12] fix test --- test/resources/Account_test.py | 59 +++++++++++++++++----------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/test/resources/Account_test.py b/test/resources/Account_test.py index 3c8d604..9777b1d 100644 --- a/test/resources/Account_test.py +++ b/test/resources/Account_test.py @@ -320,18 +320,14 @@ def test_retrieve_card_brands(setup): test_credit_card_account = setup['test_credit_card_account'] card_retrieve_response = method.accounts(test_credit_card_account['id']).card_brands.retrieve(card_brand_create_response['id']) - expect_results: AccountCardBrand = { + + expect_results = { 'id': card_brand_create_response['id'], 'account_id': test_credit_card_account['id'], 'network': 'visa', 'status': 'completed', 'issuer': card_brand_create_response['issuer'], 'last4': '1580', - 'brands': [{ - 'art_id': 'art_pCc787cy3ciWp', - 'id': 'brand_UBwVzXjpP4PJ6', - 'name': 'Chase Sapphire Reserve', - 'url': 'https://static.methodfi.com/card_brands/1b7ccaba6535cb837f802d968add4700.png'}], 'shared': False, 'source': "network", 'error': None, @@ -339,34 +335,39 @@ def test_retrieve_card_brands(setup): 'updated_at': card_retrieve_response['updated_at'], } - assert card_retrieve_response == expect_results + for k, v in expect_results.items(): + assert card_retrieve_response[k] == v + + brand = card_retrieve_response['brands'][0] + assert brand['id'] == 'brand_UBwVzXjpP4PJ6' + assert brand['name'] == 'Chase Sapphire Reserve' + assert brand['url'] == 'https://static.methodfi.com/card_brands/1b7ccaba6535cb837f802d968add4700.png' + assert isinstance(brand['art_id'], str) and brand['art_id'].startswith('art_') @pytest.mark.asyncio async def test_list_card_brands(setup): test_credit_card_account = setup['test_credit_card_account'] - - card_brands_list_response = method.accounts(test_credit_card_account['id']).card_brands.list() - - expect_results: AccountCardBrand = { - 'id': card_brand_create_response['id'], - 'account_id': test_credit_card_account['id'], - 'network': 'visa', - 'status': 'completed', - 'issuer': card_brand_create_response['issuer'], - 'last4': '1580', - 'brands': [{ - 'art_id': 'art_pCc787cy3ciWp', - 'id': 'brand_UBwVzXjpP4PJ6', - 'name': 'Chase Sapphire Reserve', - 'url': 'https://static.methodfi.com/card_brands/1b7ccaba6535cb837f802d968add4700.png'}], - 'shared': False, - 'source': "network", - 'error': None, - 'created_at': card_brands_list_response[0]['created_at'], - 'updated_at': card_brands_list_response[0]['updated_at'], - } - assert card_brands_list_response[0] == expect_results + card_brands_list_response = method.accounts(test_credit_card_account['id']).card_brands.list() + result = card_brands_list_response[0] + + assert result['id'] == card_brand_create_response['id'] + assert result['account_id'] == test_credit_card_account['id'] + assert result['network'] == 'visa' + assert result['status'] == 'completed' + assert result['issuer'] == card_brand_create_response['issuer'] + assert result['last4'] == '1580' + assert result['shared'] is False + assert result['source'] == 'network' + assert result['error'] is None + assert result['created_at'] == result['created_at'] + assert result['updated_at'] == result['updated_at'] + + brand = result['brands'][0] + assert brand['id'] == 'brand_UBwVzXjpP4PJ6' + assert brand['name'] == 'Chase Sapphire Reserve' + assert brand['url'] == 'https://static.methodfi.com/card_brands/1b7ccaba6535cb837f802d968add4700.png' + assert isinstance(brand['art_id'], str) and brand['art_id'].startswith('art_') def test_create_payoffs(setup): global payoff_create_response From d65cc148d65b95e5f62e59a07da2e26b8bd7ab90 Mon Sep 17 00:00:00 2001 From: Reza Tabrizi <63474681+rezabrizi@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:57:37 -0500 Subject: [PATCH 11/12] Address pr comments --- method/resources/Entities/Connect.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/method/resources/Entities/Connect.py b/method/resources/Entities/Connect.py index 94bb92e..6bd8f93 100644 --- a/method/resources/Entities/Connect.py +++ b/method/resources/Entities/Connect.py @@ -52,6 +52,13 @@ class ConnectExpandOpts(TypedDict): class ConnectResourceListOpts(ResourceListOpts, ConnectExpandOpts): pass +class ConnectCreateOpts(TypedDict): + products: Optional[List[AccountProductsEligibleForAutomaticExecutionLiteral]], + subscriptions: Optional[List[AccountSubscriptionsEligibleForAutomaticExecutionLiteral]] + + + + class EntityConnectResource(Resource): def __init__(self, config: Configuration): super(EntityConnectResource, self).__init__(config.add_path("connect")) @@ -63,17 +70,11 @@ def list( self, opts: Optional[ConnectResourceListOpts] = None ) -> MethodResponse[List[EntityConnect]]: return super(EntityConnectResource, self)._list(opts) - + def create( self, - products: Optional[List[AccountProductsEligibleForAutomaticExecutionLiteral]] = None, - subscriptions: Optional[List[AccountSubscriptionsEligibleForAutomaticExecutionLiteral]] = None, - opts: Optional[ConnectExpandOpts] = None + opts: ConnectCreateOpts = {}, + params: Optional[ConnectExpandOpts] = None ) -> MethodResponse[EntityConnect]: - data = {} - if products: - data["products"] = products - if subscriptions: - data["subscriptions"] = subscriptions - return super(EntityConnectResource, self)._create(data=data, params=opts) + return super(EntityConnectResource, self)._create(data=opts, params=params) \ No newline at end of file From 5606aff2a7a6f90f1b22b77915dc0b60cb0e9ed9 Mon Sep 17 00:00:00 2001 From: Reza Tabrizi <63474681+rezabrizi@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:58:11 -0500 Subject: [PATCH 12/12] remove comma --- method/resources/Entities/Connect.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/method/resources/Entities/Connect.py b/method/resources/Entities/Connect.py index 6bd8f93..71bde1d 100644 --- a/method/resources/Entities/Connect.py +++ b/method/resources/Entities/Connect.py @@ -53,7 +53,7 @@ class ConnectResourceListOpts(ResourceListOpts, ConnectExpandOpts): pass class ConnectCreateOpts(TypedDict): - products: Optional[List[AccountProductsEligibleForAutomaticExecutionLiteral]], + products: Optional[List[AccountProductsEligibleForAutomaticExecutionLiteral]] subscriptions: Optional[List[AccountSubscriptionsEligibleForAutomaticExecutionLiteral]]