diff --git a/lago_python_client/customers/clients.py b/lago_python_client/customers/clients.py index ef4aa82..c198e0c 100644 --- a/lago_python_client/customers/clients.py +++ b/lago_python_client/customers/clients.py @@ -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 ( @@ -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, @@ -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( diff --git a/lago_python_client/gross_revenues/clients.py b/lago_python_client/gross_revenues/clients.py index b6970b6..e88106d 100644 --- a/lago_python_client/gross_revenues/clients.py +++ b/lago_python_client/gross_revenues/clients.py @@ -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): @@ -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, diff --git a/lago_python_client/invoice_collections/clients.py b/lago_python_client/invoice_collections/clients.py index 09591c4..f7807bb 100644 --- a/lago_python_client/invoice_collections/clients.py +++ b/lago_python_client/invoice_collections/clients.py @@ -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): @@ -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, diff --git a/lago_python_client/invoiced_usages/clients.py b/lago_python_client/invoiced_usages/clients.py index 8d7c2f9..e74d9bd 100644 --- a/lago_python_client/invoiced_usages/clients.py +++ b/lago_python_client/invoiced_usages/clients.py @@ -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): @@ -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, diff --git a/lago_python_client/mixins.py b/lago_python_client/mixins.py index 6cdef31..4e44ecc 100644 --- a/lago_python_client/mixins.py +++ b/lago_python_client/mixins.py @@ -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 @@ -12,6 +12,7 @@ from .services.json import to_json from .services.request import ( + QueryPairs, make_headers, make_url, send_delete_request, @@ -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.""" @@ -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.""" @@ -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.""" diff --git a/lago_python_client/mrrs/clients.py b/lago_python_client/mrrs/clients.py index 93e3ba9..59bb03d 100644 --- a/lago_python_client/mrrs/clients.py +++ b/lago_python_client/mrrs/clients.py @@ -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): @@ -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, diff --git a/lago_python_client/overdue_balances/clients.py b/lago_python_client/overdue_balances/clients.py index 436d751..8432ef0 100644 --- a/lago_python_client/overdue_balances/clients.py +++ b/lago_python_client/overdue_balances/clients.py @@ -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): @@ -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( diff --git a/lago_python_client/services/request.py b/lago_python_client/services/request.py index ed6ef8c..76f1830 100644 --- a/lago_python_client/services/request.py +++ b/lago_python_client/services/request.py @@ -19,12 +19,14 @@ 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( @@ -32,7 +34,7 @@ def make_url( 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 "", diff --git a/lago_python_client/wallets/clients.py b/lago_python_client/wallets/clients.py index 2918c69..8671040 100644 --- a/lago_python_client/wallets/clients.py +++ b/lago_python_client/wallets/clients.py @@ -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 @@ -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, @@ -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, diff --git a/tests/test_request_services.py b/tests/test_request_services.py index 76731d2..db1320a 100644 --- a/tests/test_request_services.py +++ b/tests/test_request_services.py @@ -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"