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
4 changes: 3 additions & 1 deletion method/method.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
from method.resources.Webhook import WebhookResource
from method.resources.HealthCheck import PingResponse, HealthCheckResource
from method.resources.Simulate import SimulateResource

from method.resources.Events import EventResource

class Method:
accounts: AccountResource
entities: EntityResource
elements: ElementResource
events: EventResource
merchants: MerchantResource
payments: PaymentResource
reports: ReportResource
Expand All @@ -29,6 +30,7 @@ def __init__(self, opts: ConfigurationOpts = None, **kwargs: ConfigurationOpts):
self.accounts = AccountResource(config)
self.entities = EntityResource(config)
self.elements = ElementResource(config)
self.events = EventResource(config)
self.merchants = MerchantResource(config)
self.payments = PaymentResource(config)
self.reports = ReportResource(config)
Expand Down
40 changes: 40 additions & 0 deletions method/resources/Events/Event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from typing import TypedDict, Optional, Dict, Any, List, Literal
from method.resource import MethodResponse, Resource, ResourceListOpts
from method.configuration import Configuration
from method.resources.Webhook import WebhookTypesLiterals

EventResourceTypesLiterals = Literal[
'account',
'credit_score',
'attribute',
'connect'
]

class EventDiff(TypedDict):
before: Optional[Dict[str, Any]]
after: Optional[Dict[str, Any]]

class Event(TypedDict):
id: str
type: WebhookTypesLiterals
resource_id: str
resource_type: EventResourceTypesLiterals
data: Dict[str, Any]
diff: EventDiff
updated_at: str
created_at: str

class EventListOpts(ResourceListOpts):
resource_id: Optional[str]
resource_type: Optional[EventResourceTypesLiterals]
type: Optional[WebhookTypesLiterals]

class EventResource(Resource):
def __init__(self, config: Configuration):
super(EventResource, self).__init__(config.add_path('events'))

def retrieve(self, evt_id: str) -> MethodResponse[Event]:
return super(EventResource, self)._get_with_id(evt_id)

def list(self, params: Optional[EventListOpts] = None) -> MethodResponse[List[Event]]:
return super(EventResource, self)._list(params)
1 change: 1 addition & 0 deletions method/resources/Events/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from method.resources.Events.Event import Event, EventResource
16 changes: 16 additions & 0 deletions method/resources/Simulate/Events.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from typing import Dict, TypedDict, Optional
from method.resource import MethodResponse, Resource
from method.configuration import Configuration
from method.resources.Webhook import WebhookTypesLiterals

class SimulateEventsOpts(TypedDict):
type: WebhookTypesLiterals
entity_id: Optional[str]
account_id: Optional[str]

class SimulateEventsResource(Resource):
def __init__(self, config: Configuration):
super(SimulateEventsResource, self).__init__(config.add_path('events'))

def create(self, opts: SimulateEventsOpts) -> MethodResponse[Dict]:
return super(SimulateEventsResource, self)._create(opts)
4 changes: 3 additions & 1 deletion method/resources/Simulate/Simulate.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
from method.configuration import Configuration
from method.resources.Simulate.Payments import SimulatePaymentResource
from method.resources.Simulate.Accounts import SimulateAccountResource

from method.resources.Simulate.Events import SimulateEventsResource

class SimulateResource(Resource):
payments: SimulatePaymentResource
accounts: SimulateAccountResource
events: SimulateEventsResource

def __init__(self, config: Configuration):
_config = config.add_path('simulate')
super(SimulateResource, self).__init__(_config)
self.payments = SimulatePaymentResource(_config)
self.accounts = SimulateAccountResource(_config)
self.events = SimulateEventsResource(_config)
50 changes: 44 additions & 6 deletions method/resources/Webhook.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,58 @@
'account.update',
'entity.update',
'entity.create',
'account_verification.create',
'account_verification.update',
'payment_reversal.create',
'payment_reversal.update',
'connection.create',
'connection.update',
'account_verification.create',
'account_verification.update',
'transaction.create',
'transaction.update',
'report.create',
'report.update',
'product.create',
'product.update',
'subscription.create',
'subscription.update',
'credit_score.create',
'credit_score.update',

# Deprecated
'account_verification.sent',
'account_verification.returned'
'payoff.create',
'payoff.update',
'entity_verification_session.create',
'entity_verification_session.update',
'connect.create',
'connect.update',
'balance.create',
'balance.update',
'identity.create',
'identity.update',
'account_verification_session.create',
'account_verification_session.update',
'card_brand.create',
'card_brand.update',
'sensitive.create',
'sensitive.update',
'update.create',
'update.update',
'attribute.create',
'attribute.update',
'account.opened',
'account.closed',
'credit_score.increased',
'credit_score.decreased',
'attribute.credit_health_credit_card_usage.increased',
'attribute.credit_health_credit_card_usage.decreased',
'attribute.credit_health_derogatory_marks.increased',
'attribute.credit_health_derogatory_marks.decreased',
'attribute.credit_health_hard_inquiries.increased',
'attribute.credit_health_hard_inquiries.decreased',
'attribute.credit_health_total_accounts.increased',
'attribute.credit_health_total_accounts.decreased',
'attribute.credit_health_credit_age.increased',
'attribute.credit_health_credit_age.decreased',
'attribute.credit_health_payment_history.increased',
'attribute.credit_health_payment_history.decreased'
]


Expand All @@ -37,13 +73,15 @@ class Webhook(TypedDict):
metadata: Optional[Dict[str, Any]]
created_at: str
updated_at: str
expand_event: bool


class WebhookCreateOpts(TypedDict):
type: WebhookTypesLiterals
url: str
auth_token: Optional[str]
metadata: Optional[Dict[str, Any]]
expand_event: Optional[bool]


class WebhookResource(Resource):
Expand Down
3 changes: 2 additions & 1 deletion method/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@
from method.resources.HealthCheck import PingResponse, HealthCheckResource
from method.resources.Merchant import Merchant, MerchantProviderIds, MerchantResource
from method.resources.Report import Report, ReportCreateOpts, ReportResource
from method.resources.Webhook import Webhook, WebhookCreateOpts, WebhookResource
from method.resources.Webhook import Webhook, WebhookCreateOpts, WebhookResource
from method.resources.Events.Event import Event, EventResource
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setup(
name='method-python',
version='1.1.1',
version='1.1.2',
description='Python library for the Method API',
long_description='Python library for the Method API',
long_description_content_type='text/x-rst',
Expand Down
4 changes: 2 additions & 2 deletions test/resources/Account_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ def test_create_card_brands(setup):
'account_id': test_credit_card_account['id'],
'network': 'visa',
'status': 'completed',
'issuer': None,
'issuer': card_brand_create_response['issuer'],
'last4': '1580',
'brands': card_brand_create_response['brands'],
'shared': False,
Expand All @@ -288,7 +288,7 @@ def test_retrieve_card_brands(setup):
'account_id': test_credit_card_account['id'],
'network': 'visa',
'status': 'completed',
'issuer': None,
'issuer': card_brand_create_response['issuer'],
'last4': '1580',
'brands': card_brand_create_response['brands'],
'shared': False,
Expand Down
6 changes: 4 additions & 2 deletions test/resources/Entity_test.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from datetime import datetime, timedelta
import os
from method.resources.Entities.Attributes import EntityAttributes
import pytest
Expand Down Expand Up @@ -239,7 +240,8 @@ def test_update_entity():

def test_list_entities():
global entities_list_response
entities_list_response = method.entities.list()
# list only those entities created in past day, in the format of YYYY-MM-DD
entities_list_response = method.entities.list( {'from_date': (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%d')} )
entities_list_response = [entity['id'] for entity in entities_list_response]

assert entities_create_response['id'] in entities_list_response
Expand Down Expand Up @@ -371,7 +373,7 @@ def get_credit_score():
{
'score': credit_score_retrieve_response['scores'][0]['score'],
'source': 'equifax',
'model': 'vantage_3',
'model': 'vantage_4',
'factors': credit_score_retrieve_response['scores'][0]['factors'],
'created_at': credit_score_retrieve_response['scores'][0]['created_at']
}
Expand Down
77 changes: 77 additions & 0 deletions test/resources/Event_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
from time import sleep
import os
import pytest
from method import Method
from dotenv import load_dotenv

load_dotenv()

API_KEY = os.getenv('API_KEY')
method = Method(env='dev', api_key=API_KEY)

@pytest.fixture(scope='module')
def setup():
entity_response = method.entities.create({
'type': 'individual',
'individual': {
'first_name': 'Kevin',
'last_name': 'Doyle',
'phone': '+15121231111',
}
})

method.entities(entity_response['id']).verification_sessions.create({
'type': 'phone',
'method': 'byo_sms',
'byo_sms': {
'timestamp': '2024-03-15T00:00:00.000Z'
}
})

method.entities(entity_response['id']).verification_sessions.create({
'type': 'identity',
'method': 'kba',
'kba': {}
})

connect_response = method.entities(entity_response['id']).connect.create()
account_response = method.accounts.list({'holder_id': entity_response['id']})
attribute_response = method.entities(entity_response['id']).attributes.create()
credit_score_response = method.entities(entity_response['id']).credit_scores.create()

return {
'entity_response': entity_response,
'connect_response': connect_response,
'account_response': account_response,
'attribute_response': attribute_response,
'credit_score_response': credit_score_response
}

def test_simulate_account_closed(setup):
method.simulate.events.create({
'type': 'account.closed',
'account_id': setup['account_response'][0]['id']
})

# Wait for event to be created
sleep(1)

events_list_response = method.events.list({
'resource_id': setup['account_response'][0]['id']
})

event_response = events_list_response[0]
event_retrieve_response = method.events.retrieve(event_response['id'])

expect_results = {
'id': event_response['id'],
'created_at': event_response['created_at'],
'updated_at': event_response['updated_at'],
'type': 'account.closed',
'resource_id': setup['account_response'][0]['id'],
'resource_type': 'account',
'data': event_response['data'],
'diff': event_response['diff']
}

assert event_retrieve_response == expect_results
6 changes: 4 additions & 2 deletions test/resources/Webhook_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ def test_create_webhooks():
'url': 'https://dev.methodfi.com',
'metadata': None,
'created_at': webhooks_create_response['created_at'],
'updated_at': webhooks_create_response['updated_at']
'updated_at': webhooks_create_response['updated_at'],
'expand_event': webhooks_create_response['expand_event']
}

assert webhooks_create_response == expect_results
Expand All @@ -45,7 +46,8 @@ def test_retrieve_webhook():
'url': 'https://dev.methodfi.com',
'metadata': None,
'created_at': webhooks_retrieve_response['created_at'],
'updated_at': webhooks_retrieve_response['updated_at']
'updated_at': webhooks_retrieve_response['updated_at'],
'expand_event': webhooks_retrieve_response['expand_event']
}

assert webhooks_retrieve_response == expect_results
Expand Down