Skip to content

Commit

Permalink
Merge pull request #194 from ntropy-network/v3_api_rc
Browse files Browse the repository at this point in the history
V3 api rc
  • Loading branch information
adgsantos authored Nov 6, 2024
2 parents a7a07fb + fc51d7e commit 29ccea7
Show file tree
Hide file tree
Showing 40 changed files with 1,664 additions and 1,020 deletions.
27 changes: 12 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,21 @@ $ python3 -m pip install --upgrade 'ntropy-sdk'
Enriching your first transaction requires an `SDK` object and an input `Transaction` object. The API key can be set in the environment variable `NTROPY_API_KEY` or in the `SDK` constructor:

```python
from ntropy_sdk import SDK, Transaction
from ntropy_sdk import SDK

sdk = SDK("YOUR-API-KEY")
tx = Transaction(
description = "AMAZON WEB SERVICES",
entry_type = "outgoing",
amount = 12042.37,
iso_currency_code = "USD",
date = "2021-11-01",
transaction_id = "4yp49x3tbj9mD8DB4fM8DDY6Yxbx8YP14g565Xketw3tFmn",
country = "US",
account_holder_id = "id-1",
account_holder_type = "business",
account_holder_name = "Robin's Tacos",
r = sdk.transactions.create(
id="4yp49x3tbj9mD8DB4fM8DDY6Yxbx8YP14g565Xketw3tFmn",
description="AMAZON WEB SERVICES",
entry_type="outgoing",
amount=12042.37,
currency="USD",
date="2021-11-01",
location=dict(
country="US"
),
)

enriched_tx = sdk.add_transactions([tx])[0]
print(enriched_tx.merchant)
print(r)
```

The returned `EnrichedTransaction` contains the added information by Ntropy API. You can consult the Enrichment section of the documentation for more information on the parameters for both `Transaction` and `EnrichedTransaction`.
Expand Down
70 changes: 48 additions & 22 deletions ntropy_sdk/__init__.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,57 @@
__version__ = "4.26.0"

from ntropy_sdk.ntropy_sdk import (
AccountHolder,
AccountHolderType,
Transaction,
SDK,
Batch,
__version__ = "5.0.1"

from typing import TYPE_CHECKING, Optional
import requests


if TYPE_CHECKING:
from typing_extensions import TypedDict

class ExtraKwargs(TypedDict, total=False):
request_id: Optional[str]
api_key: Optional[str]
session: Optional[requests.Session]
retries: int
timeout: int
retry_on_unhandled_exception: bool
extra_headers: Optional[dict]


from .sdk import SDK
from .v2.errors import (
NtropyError,
NtropyBatchError,
EnrichedTransaction,
EnrichedTransactionList,
BankStatement,
BankStatementRequest,
Report,
NtropyDatasourceError,
NtropyTimeoutError,
NtropyHTTPError,
NtropyValidationError,
NtropyQuotaExceededError,
NtropyNotSupportedError,
NtropyResourceOccupiedError,
NtropyServerConnectionError,
NtropyRateLimitError,
NtropyNotFoundError,
NtropyNotAuthorizedError,
NtropyValueError,
NtropyRuntimeError,
)


__all__ = (
"AccountHolder",
"AccountHolderType",
"Transaction",
"SDK",
"Batch",
"NtropyError",
"NtropyBatchError",
"EnrichedTransaction",
"EnrichedTransactionList",
"BankStatement",
"BankStatementRequest",
"Report",
"NtropyDatasourceError",
"NtropyTimeoutError",
"NtropyHTTPError",
"NtropyValidationError",
"NtropyQuotaExceededError",
"NtropyNotSupportedError",
"NtropyResourceOccupiedError",
"NtropyServerConnectionError",
"NtropyRateLimitError",
"NtropyNotFoundError",
"NtropyNotAuthorizedError",
"NtropyValueError",
"NtropyRuntimeError",
)
162 changes: 162 additions & 0 deletions ntropy_sdk/account_holders.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import uuid
from datetime import datetime
from enum import Enum
from typing import Optional, TYPE_CHECKING, Union

from pydantic import BaseModel, Field

from ntropy_sdk.paging import PagedResponse
from ntropy_sdk.transactions import RecurrenceGroup, RecurrenceGroups
from ntropy_sdk.utils import pydantic_json

if TYPE_CHECKING:
from ntropy_sdk import ExtraKwargs
from ntropy_sdk import SDK
from typing_extensions import Unpack


class AccountHolderType(str, Enum):
consumer = "consumer"
business = "business"


class AccountHolderCreate(BaseModel):
id: str = Field(
description="The unique ID of the account holder of the transaction",
min_length=1,
)
type: AccountHolderType = Field(
description="The type of the account holder. ",
)
name: Optional[str] = Field(
default=None,
description="The name of the account holder",
)
request_id: Optional[str] = None


class AccountHolderResponse(AccountHolderCreate):
created_at: datetime = Field(
...,
description="Date of creation of the account holder",
)


class AccountHoldersResource:
def __init__(self, sdk: "SDK"):
self._sdk = sdk

def list(
self,
*,
created_before: Optional[datetime] = None,
created_after: Optional[datetime] = None,
cursor: Optional[str] = None,
limit: Optional[int] = None,
**extra_kwargs: "Unpack[ExtraKwargs]",
) -> PagedResponse[AccountHolderResponse]:
"""List all account holders"""

request_id = extra_kwargs.get("request_id")
if request_id is None:
request_id = uuid.uuid4().hex
extra_kwargs["request_id"] = request_id
resp = self._sdk.retry_ratelimited_request(
method="GET",
url="/v3/account_holders",
params={
"created_before": created_before,
"created_after": created_after,
"cursor": cursor,
"limit": limit,
},
**extra_kwargs,
)
page = PagedResponse[AccountHolderResponse](
**resp.json(),
request_id=resp.headers.get("x-request-id", request_id),
_resource=self,
_extra_kwargs=extra_kwargs,
)
for t in page.data:
t.request_id = request_id
return page

def get(
self, id: str, **extra_kwargs: "Unpack[ExtraKwargs]"
) -> AccountHolderResponse:
"""Retrieve an account holder"""

request_id = extra_kwargs.get("request_id")
if request_id is None:
request_id = uuid.uuid4().hex
extra_kwargs["request_id"] = request_id
resp = self._sdk.retry_ratelimited_request(
method="GET",
url=f"/v3/account_holders/{id}",
**extra_kwargs,
)
return AccountHolderResponse(
**resp.json(), request_id=resp.headers.get("x-request-id", request_id)
)

def create(
self,
id: str,
type: Union[AccountHolderType, str],
name: Optional[str] = None,
**extra_kwargs: "Unpack[ExtraKwargs]",
) -> AccountHolderResponse:
"""Create an account holder"""

request_id = extra_kwargs.get("request_id")
if request_id is None:
request_id = uuid.uuid4().hex
extra_kwargs["request_id"] = request_id
resp = self._sdk.retry_ratelimited_request(
method="POST",
url="/v3/account_holders",
payload_json_str=pydantic_json(
AccountHolderCreate(
id=id,
type=type,
name=name,
)
),
**extra_kwargs,
)
return AccountHolderResponse(
**resp.json(), request_id=resp.headers.get("x-request-id", request_id)
)

def recurring_groups(
self,
id: str,
**extra_kwargs: "Unpack[ExtraKwargs]",
) -> RecurrenceGroups:
request_id = extra_kwargs.get("request_id")
if request_id is None:
request_id = uuid.uuid4().hex
extra_kwargs["request_id"] = request_id
resp = self._sdk.retry_ratelimited_request(
method="POST",
url=f"/v3/account_holders/{id}/recurring_groups",
**extra_kwargs,
)
return RecurrenceGroups(
groups=[RecurrenceGroup(**r) for r in resp.json()],
request_id=resp.headers.get("x-request-id", request_id),
)

def delete(self, id: str, **extra_kwargs: "Unpack[ExtraKwargs]"):
"""Retrieve an account holder"""

request_id = extra_kwargs.get("request_id")
if request_id is None:
request_id = uuid.uuid4().hex
extra_kwargs["request_id"] = request_id
self._sdk.retry_ratelimited_request(
method="DELETE",
url=f"/v3/account_holders/{id}",
**extra_kwargs,
)
Loading

0 comments on commit 29ccea7

Please sign in to comment.