Skip to content

Commit

Permalink
chore(docs): remove old migration guide (#251)
Browse files Browse the repository at this point in the history
  • Loading branch information
stainless-bot committed Oct 25, 2023
1 parent a7d0f8d commit ecb2c32
Show file tree
Hide file tree
Showing 2 changed files with 0 additions and 247 deletions.
246 changes: 0 additions & 246 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
# Modern Treasury Python API library

> **Migration Guide**
>
> We've made some major improvements to how you pass arguments to methods which will require migrating your existing code.
>
> If you want to migrate to the new patterns incrementally you can do so by installing `v0.5.0`. This release contains both
> the new and old patterns with a backwards compatibility layer.
>
> You can find a guide to migrating in [this document](#migration-guide).
[![PyPI version](https://img.shields.io/pypi/v/modern-treasury.svg)](https://pypi.org/project/modern-treasury/)

The Modern Treasury Python library provides convenient access to the Modern Treasury REST API from any Python 3.7+
Expand Down Expand Up @@ -327,243 +318,6 @@ client = ModernTreasury(

By default the library closes underlying HTTP connections whenever the client is [garbage collected](https://docs.python.org/3/reference/datamodel.html#object.__del__). You can manually close the client using the `.close()` method if desired, or with a context manager that closes when exiting.

# Migration guide

This section outlines the features that were deprecated in `v0.5.0`, and subsequently removed in `v0.6.0` and how to migrate your code.

## Breaking changes

### TypedDict → keyword arguments

The way you pass arguments to methods has been changed from a single `TypedDict` to individual arguments. For example, this snippet:

```python
account = await client.external_accounts.create(
{
"name": "my bank",
"counterparty_id": "123",
}
)
```

Now becomes:

```python
account = await client.external_accounts.create(
name="my bank",
counterparty_id="123",
)
```

#### Migrating

The easiest way to make your code compatible with this change is to add `**{`, for example:

```diff
- account = await client.external_accounts.create({
- "name": "my bank",
- "counterparty_id": "123",
- })
+ account = await client.external_accounts.create(**{
+ "name": "my bank",
+ "counterparty_id": "123",
+ })
```

However, it is highly recommended to completely switch to explicit keyword arguments:

```diff
- account = await client.external_accounts.create({
- "name": "my bank",
- "counterparty_id": "123",
- })
+ account = await client.external_accounts.create(
+ name='my bank',
+ counterparty_id='123',
+ )
```

### Named path arguments

All but the last path parameter must now be passed as named arguments instead of positional arguments, for example, for a method that calls the endpoint `/api/{itemizable_type}/{itemizable_id}/line_items/{id}` you would've been able to call the method like this:

```python
line_item = await client.line_items.retrieve(
"itemizable_type",
"itemizable_id",
"my_line_id",
)
```

But now you must call the method like this:

```python
line_item = await client.line_items.retrieve(
"my_line_id",
itemizable_id="itemizable_id",
itemizable_type="itemizable_type",
)
```

If you have type checking enabled in your IDE it will tell you which parts of your code need to be updated.

### Request options

You used to be able to set request options on a per-method basis, now you can only set them on the client. There are two methods that you can use to make this easy, `with_options` and `copy`.

If you need to make multiple requests with changed options, you can use `.copy()` to get a new client object with those options. This can be useful if you need to set a custom header for multiple requests, for example:

```python
copied = client.copy(default_headers={"X-My-Header": "Foo"})
account = await copied.external_accounts.create(
name="my bank",
counterparty_id="123",
)
await copied.cards.provision(card.token, digital_wallet="GOOGLE_PAY")
```

If you just need to override one of the client options for one request, you can use `.with_options()`, for example:

```python
await client.with_options(timeout=None).external_accounts.create(
name="my bank",
counterparty_id="123",
)
```

It should be noted that the `.with_options()` method is simply an alias to `.copy()`, you can use them interchangeably.

You can pass nearly every argument that is supported by the Client `__init__` method to the `.copy()` method, except for `proxies` and `transport`.

```python
copied = client.copy(
api_key="...",
timeout=httpx.Timeout(read=10),
max_retries=5,
default_headers={
"X-My-Header": "value",
},
default_query={
"my_default_param": "value",
},
)
```

## New features

### Pass custom headers

If you need to add additional headers to a request you can easily do so with the `extra_headers` argument:

```python
account = await client.external_accounts.create(
name="my bank",
counterparty_id="123",
extra_headers={
"X-Foo": "my header",
},
)
```

### Pass custom JSON properties

You can add additional properties to the JSON request body that are not included directly in the method definition through the `extra_body` argument. This can be useful when there are in new properties in the API that are in beta and aren't in the SDK yet.

```python
account = await client.external_accounts.create(
name="my bank",
counterparty_id="123",
extra_body={
"special_prop": "foo",
},
)
# sends this to the API:
# {"name": "my bank", "counterparty_id": "123", "special_prop": "foo"}
```

### Pass custom query parameters

You can add additional query parameters that aren't specified in the method definition through the `extra_query` argument. This can be useful when there are any new/beta query parameters that are not yet in the SDK.

```python
account = await client.external_accounts.create(
name="my bank",
counterparty_id="123",
extra_query={
"special_param": "bar",
},
)
# makes the request to this URL:
# https://app.moderntreasury.com/api/external_accounts?special_param=bar
```

## Array items type name improvements

In `v1.5.0` we improved the names for types that come from arrays so that they always us a singular name, e.g. `LedgerEntries` -> `LedgerEntry`.

We've added aliases for the old type names so you can continue to use them without any breaking changes but they will be removed in the future.

Full list of all changed type names:

- `Accounts` -> `Account`
- `Balances` -> `Balance`
- `Documents` -> `Document`
- `LineItems` -> `LineItem`
- `LedgerEntries` -> `LedgerEntry`
- `AccountDetail` -> `AccountDetail`
- `RoutingDetail` -> `RoutingDetail`
- `AccountDetails` -> `AccountDetail`
- `ContactDetails` -> `ContactDetail`
- `RoutingDetails` -> `RoutingDetail`
- `ReferenceNumbers` -> `ReferenceNumber`
- `AccountsPartyAddress` -> `AccountPartyAddress`
- `AccountsAccountDetails` -> `AccountAccountDetail`
- `AccountsContactDetails` -> `AccountContactDetail`
- `AccountsRoutingDetails` -> `AccountRoutingDetail`
- `RoutingDetailBankAddress` -> `RoutingDetailBankAddress`
- `LedgerTransactionLedgerEntries` -> `LedgerTransactionLedgerEntry`
- `ReceivingAccountAccountDetails` -> `ReceivingAccountAccountDetail`
- `ReceivingAccountContactDetails` -> `ReceivingAccountContactDetail`
- `ReceivingAccountRoutingDetails` -> `ReceivingAccountRoutingDetail`
- `LedgerEntriesResultingLedgerAccountBalances` -> `LedgerEntryResultingLedgerAccountBalances`
- `LedgerEntriesResultingLedgerAccountBalancesPostedBalance` -> `LedgerEntryResultingLedgerAccountBalancesPostedBalance`
- `LedgerEntriesResultingLedgerAccountBalancesPendingBalance` -> `LedgerEntryResultingLedgerAccountBalancesPendingBalance`
- `LedgerEntriesResultingLedgerAccountBalancesAvailableBalance` -> `LedgerEntryResultingLedgerAccountBalancesAvailableBalance`

## Rich `date` and `datetime` types

We've improved the types for response fields / request params that correspond to `date` or `datetime` values!

Previously they were just raw strings but now response fields will be instances of `date` or `datetime`.

This means that if you're working with these fields and parsing them into `datetime` instances manually you will have to remove
any code that performs said parsing.

```diff
account = client.internal_accounts.retrieve('<id>')
- created_at = datetime.fromisoformat(account.created_at)
+ created_at = account.created_at
print(created_at.month)
```

For request params you can continue to pass in strings if you want to use a datetime library other than the standard library version but if you
were writing code that looked like this:

```py
dt = datetime(...)
for counterparty in client.counterparties.list(created_at_upper_bound=dt.isoformat()):
...
```

You can remove the explicit call to `isoformat`!

```diff
dt = datetime(...)
- for counterparty in client.counterparties.list(created_at_upper_bound=dt.isoformat()):
+ for counterparty in client.counterparties.list(created_at_upper_bound=dt):
...
```

## Versioning

This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:
Expand Down
1 change: 0 additions & 1 deletion requirements-dev.lock
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ pyright==1.1.332
pytest==7.1.1
pytest-asyncio==0.21.1
python-dateutil==2.8.2
pytz==2023.3.post1
respx==0.19.2
rfc3986==1.5.0
ruff==0.0.282
Expand Down

0 comments on commit ecb2c32

Please sign in to comment.