Skip to content
Closed
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
2 changes: 1 addition & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ARG VARIANT="3.9"
ARG VARIANT="3.10"
FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT}

USER vscode
Expand Down
2 changes: 1 addition & 1 deletion .python-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.9.18
3.10.18
2 changes: 1 addition & 1 deletion .stats.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
configured_endpoints: 255
openapi_spec_hash: 6076b04cad61f32c031d7cd65d3cae66
openapi_spec_hash: 0d6b366206c803272a353a0bb6942e4a
config_hash: de151ebd21a0bd391662389b310a8f49
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<!-- prettier-ignore -->
[![PyPI version](https://img.shields.io/pypi/v/increase.svg?label=pypi%20(stable))](https://pypi.org/project/increase/)

The Increase Python library provides convenient access to the Increase REST API from any Python 3.9+
The Increase Python library provides convenient access to the Increase REST API from any Python 3.10+
application. The library includes type definitions for all request params and response fields,
and offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx).

Expand Down Expand Up @@ -362,10 +362,10 @@ In an API response, a field may be explicitly `null`, or missing entirely; in ei

```py
if response.my_field is None:
if 'my_field' not in response.model_fields_set:
print('Got json like {}, without a "my_field" key present at all.')
else:
print('Got json like {"my_field": null}.')
if "my_field" not in response.model_fields_set:
print('Got json like {}, without a "my_field" key present at all.')
else:
print('Got json like {"my_field": null}.')
```

### Accessing raw response data (e.g. headers)
Expand All @@ -381,7 +381,7 @@ response = client.accounts.with_raw_response.create(
entity_id="entity_n8y8tnk2p9339ti393yi",
program_id="program_i2v2os4mwza1oetokh9i",
)
print(response.headers.get('X-My-Header'))
print(response.headers.get("X-My-Header"))

account = response.parse() # get the object that `accounts.create()` would have returned
print(account.id)
Expand Down Expand Up @@ -481,8 +481,8 @@ By default the library closes underlying HTTP connections whenever the client is
from increase import Increase

with Increase() as client:
# make requests here
...
# make requests here
...

# HTTP client is now closed
```
Expand All @@ -507,12 +507,13 @@ You can determine the version that is being used at runtime with:

```py
import increase

print(increase.__version__)
```

## Requirements

Python 3.9 or higher.
Python 3.10 or higher.

## Contributing

Expand Down
5 changes: 2 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ dependencies = [
"sniffio",
]

requires-python = ">= 3.9"
requires-python = ">= 3.10"
classifiers = [
"Typing :: Typed",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
Expand Down Expand Up @@ -126,7 +125,7 @@ filterwarnings = [
# there are a couple of flags that are still disabled by
# default in strict mode as they are experimental and niche.
typeCheckingMode = "strict"
pythonVersion = "3.9"
pythonVersion = "3.10"

exclude = [
"_dev",
Expand Down
62 changes: 24 additions & 38 deletions requirements-dev.lock
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# This file was autogenerated by uv via the following command:
# uv export -o requirements-dev.lock --no-hashes
-e .
annotated-types==0.7.0
annotated-types==0.8.0
# via pydantic
anyio==4.12.1
anyio==4.15.1
# via
# httpx
# increase
backports-asyncio-runner==1.2.0 ; python_full_version < '3.11'
# via pytest-asyncio
certifi==2026.1.4
certifi==2026.10.19
# via
# httpcore
# httpx
Expand All @@ -32,68 +32,54 @@ httpx==0.28.1
# via
# increase
# respx
idna==3.11
idna==3.20
# via
# anyio
# httpx
importlib-metadata==8.7.1
iniconfig==2.1.0 ; python_full_version < '3.10'
importlib-metadata==9.0.1
iniconfig==2.3.1
# via pytest
iniconfig==2.3.0 ; python_full_version >= '3.10'
# via pytest
markdown-it-py==3.0.0 ; python_full_version < '3.10'
# via rich
markdown-it-py==4.0.0 ; python_full_version >= '3.10'
markdown-it-py==4.2.0
# via rich
mdurl==0.1.2
# via markdown-it-py
mypy==1.17.0
mypy-extensions==1.1.0
# via mypy
nodeenv==1.10.0
nodeenv==1.11.0
# via pyright
packaging==25.0
packaging==26.3
# via pytest
pathspec==1.0.3
pathspec==1.1.1
# via mypy
pluggy==1.6.0
pluggy==1.7.0
# via pytest
pydantic==2.12.5
pydantic==2.14.1
# via increase
pydantic-core==2.41.5
pydantic-core==2.50.1
# via pydantic
pygments==2.19.2
pygments==2.21.0
# via
# pytest
# rich
pyright==1.1.399
pytest==8.4.2 ; python_full_version < '3.10'
# via
# pytest-asyncio
# pytest-xdist
pytest==9.0.2 ; python_full_version >= '3.10'
pytest==9.1.1
# via
# pytest-asyncio
# pytest-xdist
pytest-asyncio==1.2.0 ; python_full_version < '3.10'
pytest-asyncio==1.3.0 ; python_full_version >= '3.10'
pytest-asyncio==1.4.0
pytest-xdist==3.8.0
python-dateutil==2.9.0.post0 ; python_full_version < '3.10'
# via time-machine
respx==0.22.0
rich==14.2.0
ruff==0.14.13
six==1.17.0 ; python_full_version < '3.10'
# via python-dateutil
respx==0.23.1
rich==15.0.0
ruff==0.17.1
sniffio==1.3.1
# via increase
time-machine==2.19.0 ; python_full_version < '3.10'
time-machine==3.2.0 ; python_full_version >= '3.10'
tomli==2.4.0 ; python_full_version < '3.11'
time-machine==3.5.1
tomli==2.5.0 ; python_full_version < '3.11'
# via
# mypy
# pytest
typing-extensions==4.15.0
typing-extensions==4.16.0
# via
# anyio
# exceptiongroup
Expand All @@ -104,7 +90,7 @@ typing-extensions==4.15.0
# pyright
# pytest-asyncio
# typing-inspection
typing-inspection==0.4.2
typing-inspection==0.4.4
# via pydantic
zipp==3.23.0
zipp==4.1.1
# via importlib-metadata
2 changes: 1 addition & 1 deletion scripts/mock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion scripts/test
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export DEFER_PYDANTIC_BUILD=false

# Note that we need to specify the patch version here so that uv
# won't use unstable (alpha, beta, rc) releases for the tests
PY_VERSION_MIN=">=3.9.0"
PY_VERSION_MIN=">=3.10.0"
PY_VERSION_MAX=">=3.14.0"

function run_tests() {
Expand Down
2 changes: 2 additions & 0 deletions src/increase/_base_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,7 @@ def _process_response(
stream_cls: type[Stream[Any]] | type[AsyncStream[Any]] | None,
retries_taken: int = 0,
) -> ResponseT:

origin = get_origin(cast_to) or cast_to

if (
Expand Down Expand Up @@ -1672,6 +1673,7 @@ async def _process_response(
stream_cls: type[Stream[Any]] | type[AsyncStream[Any]] | None,
retries_taken: int = 0,
) -> ResponseT:

origin = get_origin(cast_to) or cast_to

if (
Expand Down
4 changes: 2 additions & 2 deletions src/increase/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,7 @@ def copy(
return self.__class__(
api_key=api_key or self.api_key,
webhook_secret=webhook_secret or self.webhook_secret,
base_url=base_url or self.base_url,
base_url=base_url or (None if environment is not None else self.base_url),
environment=environment or self._environment,
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
http_client=http_client,
Expand Down Expand Up @@ -1362,7 +1362,7 @@ def copy(
return self.__class__(
api_key=api_key or self.api_key,
webhook_secret=webhook_secret or self.webhook_secret,
base_url=base_url or self.base_url,
base_url=base_url or (None if environment is not None else self.base_url),
environment=environment or self._environment,
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
http_client=http_client,
Expand Down
7 changes: 7 additions & 0 deletions src/increase/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ def model_dump(
warnings: bool | Literal["none", "warn", "error"] = True,
fallback: Callable[[Any], Any] | None = None,
serialize_as_any: bool = False,
polymorphic_serialization: bool | None = None,
) -> dict[str, Any]:
"""Usage docs: https://docs.pydantic.dev/2.4/concepts/serialization/#modelmodel_dump

Expand All @@ -315,6 +316,7 @@ def model_dump(
fallback: A function to call when an unknown value is encountered. If not provided,
a [`PydanticSerializationError`][pydantic_core.PydanticSerializationError] error is raised.
serialize_as_any: Whether to serialize fields with duck-typing serialization behavior.
polymorphic_serialization: Whether to use model and dataclass polymorphic serialization for this call.

Returns:
A dictionary representation of the model.
Expand All @@ -333,6 +335,8 @@ def model_dump(
raise ValueError("fallback is only supported in Pydantic v2")
if exclude_computed_fields != False:
raise ValueError("exclude_computed_fields is only supported in Pydantic v2")
if polymorphic_serialization is not None:
raise ValueError("polymorphic_serialization is only supported in Pydantic v2")
dumped = super().dict( # pyright: ignore[reportDeprecated]
include=include,
exclude=exclude,
Expand Down Expand Up @@ -362,6 +366,7 @@ def model_dump_json(
warnings: bool | Literal["none", "warn", "error"] = True,
fallback: Callable[[Any], Any] | None = None,
serialize_as_any: bool = False,
polymorphic_serialization: bool | None = None,
) -> str:
"""Usage docs: https://docs.pydantic.dev/2.4/concepts/serialization/#modelmodel_dump_json

Expand Down Expand Up @@ -395,6 +400,8 @@ def model_dump_json(
raise ValueError("ensure_ascii is only supported in Pydantic v2")
if exclude_computed_fields != False:
raise ValueError("exclude_computed_fields is only supported in Pydantic v2")
if polymorphic_serialization is not None:
raise ValueError("polymorphic_serialization is only supported in Pydantic v2")
return super().json( # type: ignore[reportDeprecated]
indent=indent,
include=include,
Expand Down
4 changes: 2 additions & 2 deletions src/increase/resources/simulations/programs.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def create(
Args:
name: The name of the program being added.

bank: The bank for the program's accounts, defaults to First Internet Bank.
bank: The bank for the program's accounts, defaults to Increase Bank.

- `core_bank` - Core Bank
- `first_internet_bank` - First Internet Bank of Indiana
Expand Down Expand Up @@ -162,7 +162,7 @@ async def create(
Args:
name: The name of the program being added.

bank: The bank for the program's accounts, defaults to First Internet Bank.
bank: The bank for the program's accounts, defaults to Increase Bank.

- `core_bank` - Core Bank
- `first_internet_bank` - First Internet Bank of Indiana
Expand Down
Loading
Loading