Skip to content

Commit

Permalink
feat(api): api update (#511)
Browse files Browse the repository at this point in the history
  • Loading branch information
stainless-app[bot] committed Oct 25, 2024
1 parent efdeb23 commit 4fc6ac8
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 48 deletions.
2 changes: 1 addition & 1 deletion .stats.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
configured_endpoints: 39
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-811587ac4ba3634e1b0dd781c54c7a0cb302d612f719036f9c9683166c7197cd.yml
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-612b573cabcee39c562dc91f5b185e2a0bfdce3a262618f0098602af2199af67.yml
44 changes: 24 additions & 20 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@

### With Rye

We use [Rye](https://rye.astral.sh/) to manage dependencies so we highly recommend [installing it](https://rye.astral.sh/guide/installation/) as it will automatically provision a Python environment with the expected Python version.
We use [Rye](https://rye.astral.sh/) to manage dependencies because it will automatically provision a Python environment with the expected Python version. To set it up, run:

After installing Rye, you'll just have to run this command:
```sh
$ ./scripts/bootstrap
```

Or [install Rye manually](https://rye.astral.sh/guide/installation/) and run:

```sh
$ rye sync --all-features
Expand Down Expand Up @@ -39,17 +43,17 @@ modify the contents of the `src/finch/lib/` and `examples/` directories.

All files in the `examples/` directory are not modified by the generator and can be freely edited or added to.

```bash
```py
# add an example to examples/<your-example>.py

#!/usr/bin/env -S rye run python
```

```
chmod +x examples/<your-example>.py
```sh
$ chmod +x examples/<your-example>.py
# run the example against your api
./examples/<your-example>.py
$ ./examples/<your-example>.py
```

## Using the repository from source
Expand All @@ -58,8 +62,8 @@ If you’d like to use the repository from source, you can either install from g

To install via git:

```bash
pip install git+ssh://[email protected]/Finch-API/finch-api-python.git
```sh
$ pip install git+ssh://[email protected]/Finch-API/finch-api-python.git
```

Alternatively, you can build from source and install the wheel file:
Expand All @@ -68,29 +72,29 @@ Building this package will create two files in the `dist/` directory, a `.tar.gz

To create a distributable version of the library, all you have to do is run this command:

```bash
rye build
```sh
$ rye build
# or
python -m build
$ python -m build
```

Then to install:

```sh
pip install ./path-to-wheel-file.whl
$ pip install ./path-to-wheel-file.whl
```

## Running tests

Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests.

```bash
```sh
# you will need npm installed
npx prism mock path/to/your/openapi.yml
$ npx prism mock path/to/your/openapi.yml
```

```bash
rye run pytest
```sh
$ ./scripts/test
```

## Linting and formatting
Expand All @@ -100,14 +104,14 @@ This repository uses [ruff](https://github.com/astral-sh/ruff) and

To lint:

```bash
rye run lint
```sh
$ ./scripts/lint
```

To format and fix all ruff issues automatically:

```bash
rye run format
```sh
$ ./scripts/format
```

## Publishing and releases
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,3 +430,7 @@ print(finch.__version__)
## Requirements

Python 3.7 or higher.

## Contributing

See [the contributing documentation](./CONTRIBUTING.md).
9 changes: 8 additions & 1 deletion src/finch/_base_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@ def __init__(
self.url = url
self.params = params

@override
def __repr__(self) -> str:
if self.url:
return f"{self.__class__.__name__}(url={self.url})"
return f"{self.__class__.__name__}(params={self.params})"


class BasePage(GenericModel, Generic[_T]):
"""
Expand Down Expand Up @@ -690,7 +696,8 @@ def _calculate_retry_timeout(
if retry_after is not None and 0 < retry_after <= 60:
return retry_after

nb_retries = max_retries - remaining_retries
# Also cap retry count to 1000 to avoid any potential overflows with `pow`
nb_retries = min(max_retries - remaining_retries, 1000)

# Apply exponential backoff, but not more than the max.
sleep_seconds = min(INITIAL_RETRY_DELAY * pow(2.0, nb_retries), MAX_RETRY_DELAY)
Expand Down
3 changes: 3 additions & 0 deletions src/finch/_legacy_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,9 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
if cast_to == float:
return cast(R, float(response.text))

if cast_to == bool:
return cast(R, response.text.lower() == "true")

origin = get_origin(cast_to) or cast_to

if inspect.isclass(origin) and issubclass(origin, HttpxBinaryResponseContent):
Expand Down
3 changes: 3 additions & 0 deletions src/finch/_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
if cast_to == float:
return cast(R, float(response.text))

if cast_to == bool:
return cast(R, response.text.lower() == "true")

origin = get_origin(cast_to) or cast_to

# handle the legacy binary response case
Expand Down
14 changes: 0 additions & 14 deletions src/finch/types/account_update_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
"AccountUpdateEventDataAuthenticationMethodSupportedFieldsPayStatementPayStatementsEarnings",
"AccountUpdateEventDataAuthenticationMethodSupportedFieldsPayStatementPayStatementsEmployeeDeductions",
"AccountUpdateEventDataAuthenticationMethodSupportedFieldsPayStatementPayStatementsEmployerContributions",
"AccountUpdateEventDataAuthenticationMethodSupportedFieldsPayStatementPayStatementsEmployerDeductions",
"AccountUpdateEventDataAuthenticationMethodSupportedFieldsPayStatementPayStatementsTaxes",
"AccountUpdateEventDataAuthenticationMethodSupportedFieldsPayment",
"AccountUpdateEventDataAuthenticationMethodSupportedFieldsPaymentPayPeriod",
Expand Down Expand Up @@ -302,14 +301,6 @@ class AccountUpdateEventDataAuthenticationMethodSupportedFieldsPayStatementPaySt
name: Optional[bool] = None


class AccountUpdateEventDataAuthenticationMethodSupportedFieldsPayStatementPayStatementsEmployerDeductions(BaseModel):
amount: Optional[bool] = None

currency: Optional[bool] = None

name: Optional[bool] = None


class AccountUpdateEventDataAuthenticationMethodSupportedFieldsPayStatementPayStatementsTaxes(BaseModel):
amount: Optional[bool] = None

Expand All @@ -335,11 +326,6 @@ class AccountUpdateEventDataAuthenticationMethodSupportedFieldsPayStatementPaySt
AccountUpdateEventDataAuthenticationMethodSupportedFieldsPayStatementPayStatementsEmployerContributions
] = None

employer_deductions: Optional[
AccountUpdateEventDataAuthenticationMethodSupportedFieldsPayStatementPayStatementsEmployerDeductions
] = None
"""[DEPRECATED] Use `employer_contributions` instead"""

gross_pay: Optional[bool] = None

individual_id: Optional[bool] = None
Expand Down
12 changes: 0 additions & 12 deletions src/finch/types/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
"AuthenticationMethodSupportedFieldsPayStatementPayStatementsEarnings",
"AuthenticationMethodSupportedFieldsPayStatementPayStatementsEmployeeDeductions",
"AuthenticationMethodSupportedFieldsPayStatementPayStatementsEmployerContributions",
"AuthenticationMethodSupportedFieldsPayStatementPayStatementsEmployerDeductions",
"AuthenticationMethodSupportedFieldsPayStatementPayStatementsTaxes",
"AuthenticationMethodSupportedFieldsPayment",
"AuthenticationMethodSupportedFieldsPaymentPayPeriod",
Expand Down Expand Up @@ -297,14 +296,6 @@ class AuthenticationMethodSupportedFieldsPayStatementPayStatementsEmployerContri
name: Optional[bool] = None


class AuthenticationMethodSupportedFieldsPayStatementPayStatementsEmployerDeductions(BaseModel):
amount: Optional[bool] = None

currency: Optional[bool] = None

name: Optional[bool] = None


class AuthenticationMethodSupportedFieldsPayStatementPayStatementsTaxes(BaseModel):
amount: Optional[bool] = None

Expand All @@ -326,9 +317,6 @@ class AuthenticationMethodSupportedFieldsPayStatementPayStatements(BaseModel):
AuthenticationMethodSupportedFieldsPayStatementPayStatementsEmployerContributions
] = None

employer_deductions: Optional[AuthenticationMethodSupportedFieldsPayStatementPayStatementsEmployerDeductions] = None
"""[DEPRECATED] Use `employer_contributions` instead"""

gross_pay: Optional[bool] = None

individual_id: Optional[bool] = None
Expand Down
2 changes: 2 additions & 0 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,7 @@ class Model(BaseModel):
[3, "", 0.5],
[2, "", 0.5 * 2.0],
[1, "", 0.5 * 4.0],
[-1100, "", 7.8], # test large number potentially overflowing
],
)
@mock.patch("time.time", mock.MagicMock(return_value=1696004797))
Expand Down Expand Up @@ -1686,6 +1687,7 @@ class Model(BaseModel):
[3, "", 0.5],
[2, "", 0.5 * 2.0],
[1, "", 0.5 * 4.0],
[-1100, "", 7.8], # test large number potentially overflowing
],
)
@mock.patch("time.time", mock.MagicMock(return_value=1696004797))
Expand Down
25 changes: 25 additions & 0 deletions tests/test_legacy_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,31 @@ def test_response_parse_mismatched_basemodel(client: Finch) -> None:
response.parse(to=PydanticModel)


@pytest.mark.parametrize(
"content, expected",
[
("false", False),
("true", True),
("False", False),
("True", True),
("TrUe", True),
("FalSe", False),
],
)
def test_response_parse_bool(client: Finch, content: str, expected: bool) -> None:
response = LegacyAPIResponse(
raw=httpx.Response(200, content=content),
client=client,
stream=False,
stream_cls=None,
cast_to=str,
options=FinalRequestOptions.construct(method="get", url="/foo"),
)

result = response.parse(to=bool)
assert result is expected


def test_response_parse_custom_stream(client: Finch) -> None:
response = LegacyAPIResponse(
raw=httpx.Response(200, content=b"foo"),
Expand Down
50 changes: 50 additions & 0 deletions tests/test_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,56 @@ async def test_async_response_parse_annotated_type(async_client: AsyncFinch) ->
assert obj.bar == 2


@pytest.mark.parametrize(
"content, expected",
[
("false", False),
("true", True),
("False", False),
("True", True),
("TrUe", True),
("FalSe", False),
],
)
def test_response_parse_bool(client: Finch, content: str, expected: bool) -> None:
response = APIResponse(
raw=httpx.Response(200, content=content),
client=client,
stream=False,
stream_cls=None,
cast_to=str,
options=FinalRequestOptions.construct(method="get", url="/foo"),
)

result = response.parse(to=bool)
assert result is expected


@pytest.mark.parametrize(
"content, expected",
[
("false", False),
("true", True),
("False", False),
("True", True),
("TrUe", True),
("FalSe", False),
],
)
async def test_async_response_parse_bool(client: AsyncFinch, content: str, expected: bool) -> None:
response = AsyncAPIResponse(
raw=httpx.Response(200, content=content),
client=client,
stream=False,
stream_cls=None,
cast_to=str,
options=FinalRequestOptions.construct(method="get", url="/foo"),
)

result = await response.parse(to=bool)
assert result is expected


class OtherModel(BaseModel):
a: str

Expand Down

0 comments on commit 4fc6ac8

Please sign in to comment.