Skip to content

Commit

Permalink
feat: allow passing tuples and list values as query params
Browse files Browse the repository at this point in the history
Allows passing multiple list param values such as with 'status[]'.
  • Loading branch information
steved committed Dec 23, 2024
1 parent 7696b7b commit a5e52f4
Show file tree
Hide file tree
Showing 10 changed files with 41 additions and 37 deletions.
11 changes: 3 additions & 8 deletions lago_python_client/customers/clients.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sys
from typing import Any, Mapping, ClassVar, Type, Union
from typing import Any, Mapping, ClassVar, Type

from ..base_client import BaseClient
from ..mixins import (
Expand All @@ -10,12 +10,7 @@
)
from ..models.customer import CustomerResponse
from ..models.customer_usage import CustomerUsageResponse
from ..services.request import (
make_headers,
make_url,
send_get_request,
send_post_request,
)
from ..services.request import make_headers, make_url, send_get_request, send_post_request, QueryPairs
from ..services.response import (
get_response_data,
prepare_index_response,
Expand Down Expand Up @@ -61,7 +56,7 @@ def past_usage(
self,
resource_id: str,
external_subscription_id: str,
options: Mapping[str, Union[int, str]] = {},
options: QueryPairs = {},
) -> Mapping[str, Any]:
api_response: Response = send_get_request(
url=make_url(
Expand Down
6 changes: 3 additions & 3 deletions lago_python_client/gross_revenues/clients.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import sys
from typing import Any, ClassVar, Type, Union
from typing import Any, ClassVar, Type

from ..base_client import BaseClient
from ..mixins import FindAllCommandMixin
from ..models.gross_revenue import GrossRevenueResponse
from ..services.request import make_headers, make_url, send_get_request
from ..services.request import make_headers, make_url, send_get_request, QueryPairs
from ..services.response import get_response_data, prepare_index_response, Response

if sys.version_info >= (3, 9):
Expand All @@ -21,7 +21,7 @@ class GrossRevenueClient(
RESPONSE_MODEL: ClassVar[Type[GrossRevenueResponse]] = GrossRevenueResponse
ROOT_NAME: ClassVar[str] = "gross_revenue"

def find_all(self, options: Mapping[str, Union[int, str]] = {}) -> Mapping[str, Any]:
def find_all(self, options: QueryPairs = {}) -> Mapping[str, Any]:
api_response: Response = send_get_request(
url=make_url(
origin=self.base_url,
Expand Down
6 changes: 3 additions & 3 deletions lago_python_client/invoice_collections/clients.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import sys
from typing import Any, ClassVar, Type, Union
from typing import Any, ClassVar, Type

from ..base_client import BaseClient
from ..mixins import FindAllCommandMixin
from ..models.invoice_collection import InvoiceCollectionResponse
from ..services.request import make_headers, make_url, send_get_request
from ..services.request import make_headers, make_url, send_get_request, QueryPairs
from ..services.response import get_response_data, prepare_index_response, Response

if sys.version_info >= (3, 9):
Expand All @@ -21,7 +21,7 @@ class InvoiceCollectionClient(
RESPONSE_MODEL: ClassVar[Type[InvoiceCollectionResponse]] = InvoiceCollectionResponse
ROOT_NAME: ClassVar[str] = "invoice_collection"

def find_all(self, options: Mapping[str, Union[int, str]] = {}) -> Mapping[str, Any]:
def find_all(self, options: QueryPairs = {}) -> Mapping[str, Any]:
api_response: Response = send_get_request(
url=make_url(
origin=self.base_url,
Expand Down
6 changes: 3 additions & 3 deletions lago_python_client/invoiced_usages/clients.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import sys
from typing import Any, ClassVar, Type, Union
from typing import Any, ClassVar, Type

from ..base_client import BaseClient
from ..mixins import FindAllCommandMixin
from ..models.invoiced_usage import InvoicedUsageResponse
from ..services.request import make_headers, make_url, send_get_request
from ..services.request import make_headers, make_url, send_get_request, QueryPairs
from ..services.response import get_response_data, prepare_index_response, Response

if sys.version_info >= (3, 9):
Expand All @@ -21,7 +21,7 @@ class InvoicedUsageClient(
RESPONSE_MODEL: ClassVar[Type[InvoicedUsageResponse]] = InvoicedUsageResponse
ROOT_NAME: ClassVar[str] = "invoiced_usage"

def find_all(self, options: Mapping[str, Union[int, str]] = {}) -> Mapping[str, Any]:
def find_all(self, options: QueryPairs = {}) -> Mapping[str, Any]:
api_response: Response = send_get_request(
url=make_url(
origin=self.base_url,
Expand Down
9 changes: 5 additions & 4 deletions lago_python_client/mixins.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sys
from typing import Any, Generic, Optional, Type, TypeVar, Union
from typing import Any, Generic, Optional, Type, TypeVar

import httpx

Expand All @@ -12,6 +12,7 @@

from .services.json import to_json
from .services.request import (
QueryPairs,
make_headers,
make_url,
send_delete_request,
Expand Down Expand Up @@ -89,7 +90,7 @@ class DestroyCommandMixin(Generic[_M]):
def destroy(
self: _ClientMixin[_M],
resource_id: str,
options: Mapping[str, Union[int, str]] = {},
options: QueryPairs = {},
timeout: Optional[httpx.Timeout] = None,
) -> BaseModel:
"""Execute `destroy` command."""
Expand All @@ -116,7 +117,7 @@ class FindAllCommandMixin(Generic[_M]):

def find_all(
self: _ClientMixin[_M],
options: Mapping[str, Union[int, str]] = {},
options: QueryPairs = {},
timeout: Optional[httpx.Timeout] = None,
) -> Mapping[str, Any]:
"""Execute `find all` command."""
Expand Down Expand Up @@ -145,7 +146,7 @@ class FindCommandMixin(Generic[_M]):
def find(
self: _ClientMixin[_M],
resource_id: str,
params: Mapping[str, str] = {},
params: QueryPairs = {},
timeout: Optional[httpx.Timeout] = None,
) -> _M:
"""Execute `find` command."""
Expand Down
6 changes: 3 additions & 3 deletions lago_python_client/mrrs/clients.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import sys
from typing import Any, ClassVar, Type, Union
from typing import Any, ClassVar, Type

from ..base_client import BaseClient
from ..mixins import FindAllCommandMixin
from ..models.mrr import MrrResponse
from ..services.request import make_headers, make_url, send_get_request
from ..services.request import make_headers, make_url, send_get_request, QueryPairs
from ..services.response import get_response_data, prepare_index_response, Response

if sys.version_info >= (3, 9):
Expand All @@ -21,7 +21,7 @@ class MrrClient(
RESPONSE_MODEL: ClassVar[Type[MrrResponse]] = MrrResponse
ROOT_NAME: ClassVar[str] = "mrr"

def find_all(self, options: Mapping[str, Union[int, str]] = {}) -> Mapping[str, Any]:
def find_all(self, options: QueryPairs = {}) -> Mapping[str, Any]:
api_response: Response = send_get_request(
url=make_url(
origin=self.base_url,
Expand Down
6 changes: 3 additions & 3 deletions lago_python_client/overdue_balances/clients.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import sys
from typing import Any, ClassVar, Type, Union, Optional
from typing import Any, ClassVar, Type, Optional

import httpx

from ..base_client import BaseClient
from ..mixins import FindAllCommandMixin
from ..models.overdue_balance import OverdueBalanceResponse
from ..services.request import make_headers, make_url, send_get_request
from ..services.request import make_headers, make_url, send_get_request, QueryPairs
from ..services.response import get_response_data, prepare_index_response, Response

if sys.version_info >= (3, 9):
Expand All @@ -25,7 +25,7 @@ class OverdueBalanceClient(

def find_all(
self,
options: Mapping[str, Union[int, str]] = {},
options: QueryPairs = {},
timeout: Optional[httpx.Timeout] = None,
) -> Mapping[str, Any]:
api_response: Response = send_get_request(
Expand Down
6 changes: 4 additions & 2 deletions lago_python_client/services/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,22 @@
URI_TEMPLATE: Final[str] = "{uri_path}{uri_query}"
QUERY_TEMPLATE: Final[str] = "?{query}"

QueryPairs = Union[Mapping[str, Union[int, str, list[str]]], Sequence[tuple[str, Union[int, str]]]]


def make_url(
*,
origin: str,
path_parts: Sequence[str],
query_pairs: Mapping[str, Union[int, str]] = {},
query_pairs: QueryPairs = {},
) -> str:
"""Return url."""
return urljoin(
origin,
URI_TEMPLATE.format(
uri_path="/".join(path_parts),
uri_query=QUERY_TEMPLATE.format(
query=urlencode(query_pairs),
query=urlencode(query_pairs, doseq=True),
)
if query_pairs
else "",
Expand Down
11 changes: 3 additions & 8 deletions lago_python_client/wallets/clients.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sys
from typing import Any, ClassVar, Type, Union
from typing import Any, ClassVar, Type

from lago_python_client.base_model import BaseModel

Expand All @@ -14,12 +14,7 @@
from ..models.wallet import WalletResponse
from ..models.wallet_transaction import WalletTransactionResponse
from ..services.json import to_json
from ..services.request import (
make_headers,
make_url,
send_get_request,
send_post_request,
)
from ..services.request import make_headers, make_url, send_get_request, send_post_request, QueryPairs
from ..services.response import (
get_response_data,
prepare_object_list_response,
Expand Down Expand Up @@ -67,7 +62,7 @@ def create(self, input_object: BaseModel) -> Mapping[str, Any]:
data=get_response_data(response=api_response, key=self.ROOT_NAME),
)

def find_all(self, wallet_id: str, options: Mapping[str, Union[int, str]] = {}) -> Mapping[str, Any]:
def find_all(self, wallet_id: str, options: QueryPairs = {}) -> Mapping[str, Any]:
api_response: Response = send_get_request(
url=make_url(
origin=self.base_url,
Expand Down
11 changes: 11 additions & 0 deletions tests/test_request_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,14 @@ def test_send_post_request():
def test_send_put_request():
"""Ensure `send_put_request` service use httpx."""
assert send_put_request == httpx.put


def test_make_url_with_list_query_params():
base_url = "http://example.com"
url = make_url(origin=base_url, path_parts=("test",), query_pairs={"status[]": ["active", "terminated"]})
assert url == "http://example.com/test?status%5B%5D=active&status%5B%5D=terminated"

url = make_url(
origin=base_url, path_parts=("test",), query_pairs=(("status[]", "active"), ("status[]", "terminated"))
)
assert url == "http://example.com/test?status%5B%5D=active&status%5B%5D=terminated"

0 comments on commit a5e52f4

Please sign in to comment.