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
10 changes: 2 additions & 8 deletions mollie/api/objects/balance.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,10 @@

from .balance_report import BalanceReport
from .base import ObjectBase
from .list import ObjectList
from .list import PaginationList


class Balance(ObjectBase):
@classmethod
def get_resource_class(cls, client):
from ..resources import Balances

return Balances(client)

@property
def resource(self):
return self._get_property("resource")
Expand Down Expand Up @@ -65,7 +59,7 @@ def get_report(self, **params: Any) -> BalanceReport:

return BalanceReports(self.client, self).get_report(params=params)

def get_transactions(self, **params: Any) -> ObjectList:
def get_transactions(self, **params: Any) -> PaginationList:
from ..resources import BalanceTransactions

return BalanceTransactions(self.client, self).list(params=params)
13 changes: 0 additions & 13 deletions mollie/api/objects/balance_report.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
from typing import TYPE_CHECKING, Any

from .base import ObjectBase

if TYPE_CHECKING:
from ..client import Client
from ..resources import BalanceReports


class BalanceReport(ObjectBase):
@classmethod
def get_resource_class(cls, client: "Client", **kwargs: Any) -> "BalanceReports":
from ..resources import BalanceReports

balance = kwargs["balance"]
return BalanceReports(client, balance)

@property
def resource(self):
return self._get_property("resource")
Expand Down
13 changes: 0 additions & 13 deletions mollie/api/objects/balance_transaction.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
from typing import TYPE_CHECKING, Any

from .base import ObjectBase

if TYPE_CHECKING:
from ..client import Client
from ..resources import BalanceTransactions


class BalanceTransaction(ObjectBase):
@classmethod
def get_resource_class(cls, client: "Client", **kwargs: Any) -> "BalanceTransactions":
from ..resources import BalanceTransactions

balance = kwargs["balance"]
return BalanceTransactions(client, balance)

@classmethod
def get_object_name(cls):
# Overwrite get_object_name since BalanceTransactions gets returned by Mollie as balance_transactions.
Expand Down
9 changes: 0 additions & 9 deletions mollie/api/objects/base.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
from typing import TYPE_CHECKING, Any

from ..error import EmbedNotFound

if TYPE_CHECKING:
from ..client import Client


class ObjectBase(dict):
def __init__(self, data, client):
Expand Down Expand Up @@ -45,7 +40,3 @@ def get_embedded(self, name: str) -> dict:
def get_object_name(cls):
name = cls.__name__.lower()
return f"{name}s"

@classmethod
def get_resource_class(cls, client: "Client", **kwargs: Any) -> Any:
raise NotImplementedError # pragma: no cover
13 changes: 0 additions & 13 deletions mollie/api/objects/capture.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
from typing import TYPE_CHECKING, Any

from .base import ObjectBase

if TYPE_CHECKING:
from ..client import Client
from ..resources import PaymentCaptures


class Capture(ObjectBase):
@classmethod
def get_resource_class(cls, client: "Client", **kwargs: Any) -> "PaymentCaptures":
from ..resources import PaymentCaptures

payment = kwargs["payment"]
return PaymentCaptures(client, payment)

@property
def id(self):
return self._get_property("id")
Expand Down
6 changes: 0 additions & 6 deletions mollie/api/objects/chargeback.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@


class Chargeback(ObjectBase):
@classmethod
def get_resource_class(cls, client):
from ..resources import Chargebacks

return Chargebacks(client)

@property
def id(self):
return self._get_property("id")
Expand Down
6 changes: 0 additions & 6 deletions mollie/api/objects/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@


class Client(ObjectBase):
@classmethod
def get_resource_class(cls, client):
from ..resources import Clients

return Clients(client)

# Documented properties

@property
Expand Down
6 changes: 0 additions & 6 deletions mollie/api/objects/customer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@


class Customer(ObjectBase):
@classmethod
def get_resource_class(cls, client):
from ..resources import Customers

return Customers(client)

@property
def id(self):
return self._get_property("id")
Expand Down
6 changes: 0 additions & 6 deletions mollie/api/objects/invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@


class Invoice(ObjectBase):
@classmethod
def get_resource_class(cls, client):
from ..resources import Invoices

return Invoices(client)

@property
def id(self):
return self._get_property("id")
Expand Down
130 changes: 101 additions & 29 deletions mollie/api/objects/list.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,16 @@
from .base import ObjectBase

from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Any, Optional, Type

class UnknownObject(ObjectBase):
Comment thread
Bladieblah marked this conversation as resolved.
"""Mock object for empty lists."""
from .base import ObjectBase

@classmethod
def get_object_name(cls):
return "unknown"
if TYPE_CHECKING:
from mollie.api.client import Client
from mollie.api.resources.base import ResourceBase


class ObjectList(ObjectBase):
class ListBase(ObjectBase, ABC):
current = None

def __init__(self, result, object_type, client=None):
# If an empty dataset was injected, we mock the structure that the remainder of the clas expects.
# TODO: it would be better if the ObjectList was initiated with a list of results, rather than with
# the full datastructure as it is now, so we can remove all this mucking around with fake data,
# mocked result objects, and loads of lengthy accessor workarounds everywhere in the ObjectList.
if result == {}:
result = {"_embedded": {"unknown": []}, "count": 0}
object_type = UnknownObject

super().__init__(result, client)
self.object_type = object_type

def __len__(self):
"""Return the count field."""
return self.count
Expand Down Expand Up @@ -66,7 +53,7 @@ def __getitem__(self, key):
},
"count": len(sliced_data),
}
return ObjectList(sliced_result, self.object_type, self.client)
return self.new(sliced_result)

return super().__getitem__(key)

Expand All @@ -84,16 +71,101 @@ def has_previous(self):
"""Return True if the ObjectList contains an url for the previous set."""
return self._get_link("previous") is not None

@abstractmethod
def get_next(self):
"""Return the next set of objects in an ObjectList."""
...

@abstractmethod
def get_previous(self):
...

@property
@abstractmethod
def object_type(self):
...

@abstractmethod
def new(self, result):
...


class PaginationList(ListBase):
"""
Pagination lists are used to return a paginated list of Objects.

You can use the `has_next` and `get_next` methods to get the next page of result data from the API.
The `has_previous` and `get_previous` methods return the previous page.
"""

_parent: "ResourceBase"

def __init__(self, result: Any, parent: "ResourceBase", client: "Client"):
# If an empty dataset was injected, we mock the structure that the remainder of the clas expects.
# TODO: it would be better if the ObjectList was initiated with a list of results, rather than with
# the full datastructure as it is now, so we can remove all this mucking around with fake data,
# mocked result objects, and loads of lengthy accessor workarounds everywhere in the ObjectList.
self._parent = parent

if result == {}:
result = {"_embedded": {f"{self._parent.object_type.get_object_name()}": []}, "count": 0}
Comment thread
Bladieblah marked this conversation as resolved.

super().__init__(result, client)

def get_next(self):
"""Return the next set of objects in the paginated list."""
url = self._get_link("next")
resource = self.object_type.get_resource_class(self.client)
resp = resource.perform_api_call(resource.REST_READ, url)
return ObjectList(resp, self.object_type, self.client)
if url is None:
return None
resp = self._parent.perform_api_call(self._parent.REST_READ, url)
return PaginationList(resp, self._parent, self.client)

def get_previous(self):
"""Return the previous set of objects in an ObjectList."""
"""Return the previous set of objects in the paginated list."""
url = self._get_link("previous")
resource = self.object_type.get_resource_class(self.client)
resp = resource.perform_api_call(resource.REST_READ, url)
return ObjectList(resp, self.object_type, self.client)
if url is None:
return None
resp = self._parent.perform_api_call(self._parent.REST_READ, url)
return PaginationList(resp, self._parent, self.client)

@property
def object_type(self):
return self._parent.object_type

def new(self, result):
return PaginationList(result, self._parent, self.client)


class ObjectList(ListBase):
"""
Object lists are used to return an embedded list on an object.

It works to similar to PaginationList, but has no pagination (as all data is already embedded).
"""

_object_type: Type[ObjectBase]

def __init__(self, result: Any, object_type: Type[ObjectBase], client: Optional["Client"] = None):
# If an empty dataset was injected, we mock the structure that the remainder of the clas expects.
# TODO: it would be better if the ObjectList was initiated with a list of results, rather than with
# the full datastructure as it is now, so we can remove all this mucking around with fake data,
# mocked result objects, and loads of lengthy accessor workarounds everywhere in the ObjectList.
self._object_type = object_type

if result == {}:
result = {"_embedded": {f"{self._object_type.get_object_name()}": []}, "count": 0}
Comment thread
Bladieblah marked this conversation as resolved.

super().__init__(result, client)

def get_next(self):
"""Return the next set of objects in an ObjectList."""
return None

def get_previous(self):
return None

@property
def object_type(self):
return self._object_type

def new(self, result):
return ObjectList(result, self._object_type, self.client)
13 changes: 0 additions & 13 deletions mollie/api/objects/mandate.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
from typing import TYPE_CHECKING, Any

from .base import ObjectBase

if TYPE_CHECKING:
from ..client import Client
from ..resources import CustomerMandates


class Mandate(ObjectBase):
@classmethod
def get_resource_class(cls, client: "Client", **kwargs: Any) -> "CustomerMandates":
from ..resources import CustomerMandates

customer = kwargs["customer"]
return CustomerMandates(client, customer)

STATUS_PENDING = "pending"
STATUS_VALID = "valid"
STATUS_INVALID = "invalid"
Expand Down
6 changes: 0 additions & 6 deletions mollie/api/objects/method.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@


class Method(ObjectBase):
@classmethod
def get_resource_class(cls, client):
from ..resources import Methods

return Methods(client)

# Payment methods for Payments and Orders
APPLEPAY = "applepay"
BANCONTACT = "bancontact"
Expand Down
6 changes: 0 additions & 6 deletions mollie/api/objects/onboarding.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@


class Onboarding(ObjectBase):
@classmethod
def get_resource_class(cls, client):
from ..resources import Onboarding as OnboardingResource

return OnboardingResource(client)

STATUS_NEEDS_DATA = "needs-data"
STATUS_IN_REVIEW = "in-review" # Waiting for a valid mandate.
STATUS_COMPLETED = "completed"
Expand Down
6 changes: 0 additions & 6 deletions mollie/api/objects/order.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,6 @@ class Order(ObjectBase):
def __init__(self, data, client):
super().__init__(data, client)

@classmethod
def get_resource_class(cls, client):
from ..resources import Orders

return Orders(client)

STATUS_CREATED = "created"
STATUS_PAID = "paid"
STATUS_AUTHORIZED = "authorized"
Expand Down
13 changes: 0 additions & 13 deletions mollie/api/objects/order_line.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
from typing import TYPE_CHECKING, Any

from .base import ObjectBase

if TYPE_CHECKING:
from ..client import Client
from ..resources import OrderLines


class OrderLine(ObjectBase):
@classmethod
def get_resource_class(cls, client: "Client", **kwargs: Any) -> "OrderLines":
from ..resources import OrderLines

order = kwargs["order"]
return OrderLines(client, order)

STATUS_CREATED = "created"
STATUS_AUTHORIZED = "authorized"
STATUS_PAID = "paid"
Expand Down
Loading