From dcf866c9577a219abb273e5b34e2c95bda3404f2 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 21 Feb 2026 21:17:43 +0000 Subject: [PATCH 1/6] feat(api): api update --- .stats.yml | 6 +- README.md | 26 +- api.md | 49 --- src/cas_parser/_client.py | 162 +-------- src/cas_parser/resources/__init__.py | 56 ---- src/cas_parser/resources/access_token.py | 191 ----------- src/cas_parser/resources/credits.py | 155 --------- src/cas_parser/resources/logs.py | 307 ------------------ src/cas_parser/resources/verify_token.py | 143 -------- src/cas_parser/types/__init__.py | 8 - .../types/access_token_create_params.py | 12 - .../types/access_token_create_response.py | 18 - src/cas_parser/types/credit_check_response.py | 28 -- src/cas_parser/types/log_create_params.py | 22 -- src/cas_parser/types/log_create_response.py | 37 --- .../types/log_get_summary_params.py | 19 -- .../types/log_get_summary_response.py | 35 -- .../types/verify_token_verify_response.py | 18 - tests/api_resources/test_access_token.py | 96 ------ tests/api_resources/test_credits.py | 80 ----- tests/api_resources/test_logs.py | 175 ---------- tests/api_resources/test_verify_token.py | 80 ----- tests/test_client.py | 40 +-- 23 files changed, 37 insertions(+), 1726 deletions(-) delete mode 100644 src/cas_parser/resources/access_token.py delete mode 100644 src/cas_parser/resources/credits.py delete mode 100644 src/cas_parser/resources/logs.py delete mode 100644 src/cas_parser/resources/verify_token.py delete mode 100644 src/cas_parser/types/access_token_create_params.py delete mode 100644 src/cas_parser/types/access_token_create_response.py delete mode 100644 src/cas_parser/types/credit_check_response.py delete mode 100644 src/cas_parser/types/log_create_params.py delete mode 100644 src/cas_parser/types/log_create_response.py delete mode 100644 src/cas_parser/types/log_get_summary_params.py delete mode 100644 src/cas_parser/types/log_get_summary_response.py delete mode 100644 src/cas_parser/types/verify_token_verify_response.py delete mode 100644 tests/api_resources/test_access_token.py delete mode 100644 tests/api_resources/test_credits.py delete mode 100644 tests/api_resources/test_logs.py delete mode 100644 tests/api_resources/test_verify_token.py diff --git a/.stats.yml b/.stats.yml index 56f5a81..80a6900 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 17 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml -openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f +configured_endpoints: 12 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-6a9d3b677dcfb856dc571865c34b3fe401e4d7f0d799edfc743acb9a55800bd0.yml +openapi_spec_hash: 037703a6c741e4310fda3f57c22fa51e config_hash: 41c337f5cda03b13880617490f82bad0 diff --git a/README.md b/README.md index f7b645a..04c0f3e 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,8 @@ client = CasParser( environment="environment_1", ) -response = client.credits.check() -print(response.enabled_features) +unified_response = client.cams_kfintech.parse() +print(unified_response.demat_accounts) ``` While you can provide an `api_key` keyword argument, @@ -69,8 +69,8 @@ client = AsyncCasParser( async def main() -> None: - response = await client.credits.check() - print(response.enabled_features) + unified_response = await client.cams_kfintech.parse() + print(unified_response.demat_accounts) asyncio.run(main()) @@ -103,8 +103,8 @@ async def main() -> None: api_key=os.environ.get("CAS_PARSER_API_KEY"), # This is the default and can be omitted http_client=DefaultAioHttpClient(), ) as client: - response = await client.credits.check() - print(response.enabled_features) + unified_response = await client.cams_kfintech.parse() + print(unified_response.demat_accounts) asyncio.run(main()) @@ -135,7 +135,7 @@ from cas_parser import CasParser client = CasParser() try: - client.credits.check() + client.cams_kfintech.parse() except cas_parser.APIConnectionError as e: print("The server could not be reached") print(e.__cause__) # an underlying Exception, likely raised within httpx. @@ -178,7 +178,7 @@ client = CasParser( ) # Or, configure per-request: -client.with_options(max_retries=5).credits.check() +client.with_options(max_retries=5).cams_kfintech.parse() ``` ### Timeouts @@ -201,7 +201,7 @@ client = CasParser( ) # Override per-request: -client.with_options(timeout=5.0).credits.check() +client.with_options(timeout=5.0).cams_kfintech.parse() ``` On timeout, an `APITimeoutError` is thrown. @@ -242,11 +242,11 @@ The "raw" Response object can be accessed by prefixing `.with_raw_response.` to from cas_parser import CasParser client = CasParser() -response = client.credits.with_raw_response.check() +response = client.cams_kfintech.with_raw_response.parse() print(response.headers.get('X-My-Header')) -credit = response.parse() # get the object that `credits.check()` would have returned -print(credit.enabled_features) +cams_kfintech = response.parse() # get the object that `cams_kfintech.parse()` would have returned +print(cams_kfintech.demat_accounts) ``` These methods return an [`APIResponse`](https://github.com/CASParser/cas-parser-python/tree/main/src/cas_parser/_response.py) object. @@ -260,7 +260,7 @@ The above interface eagerly reads the full response body when you make the reque To stream the response body, use `.with_streaming_response` instead, which requires a context manager and only reads the response body once you call `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` or `.parse()`. In the async client, these are async methods. ```python -with client.credits.with_streaming_response.check() as response: +with client.cams_kfintech.with_streaming_response.parse() as response: print(response.headers.get("X-My-Header")) for line in response.iter_lines(): diff --git a/api.md b/api.md index d92590b..8ba2d2c 100644 --- a/api.md +++ b/api.md @@ -1,52 +1,3 @@ -# Credits - -Types: - -```python -from cas_parser.types import CreditCheckResponse -``` - -Methods: - -- client.credits.check() -> CreditCheckResponse - -# Logs - -Types: - -```python -from cas_parser.types import LogCreateResponse, LogGetSummaryResponse -``` - -Methods: - -- client.logs.create(\*\*params) -> LogCreateResponse -- client.logs.get_summary(\*\*params) -> LogGetSummaryResponse - -# AccessToken - -Types: - -```python -from cas_parser.types import AccessTokenCreateResponse -``` - -Methods: - -- client.access_token.create(\*\*params) -> AccessTokenCreateResponse - -# VerifyToken - -Types: - -```python -from cas_parser.types import VerifyTokenVerifyResponse -``` - -Methods: - -- client.verify_token.verify() -> VerifyTokenVerifyResponse - # CamsKfintech Types: diff --git a/src/cas_parser/_client.py b/src/cas_parser/_client.py index 02dc18a..8041bb8 100644 --- a/src/cas_parser/_client.py +++ b/src/cas_parser/_client.py @@ -31,28 +31,12 @@ ) if TYPE_CHECKING: - from .resources import ( - cdsl, - logs, - nsdl, - inbox, - smart, - credits, - kfintech, - access_token, - verify_token, - cams_kfintech, - contract_note, - ) - from .resources.logs import LogsResource, AsyncLogsResource + from .resources import cdsl, nsdl, inbox, smart, kfintech, cams_kfintech, contract_note from .resources.nsdl import NsdlResource, AsyncNsdlResource from .resources.inbox import InboxResource, AsyncInboxResource from .resources.smart import SmartResource, AsyncSmartResource - from .resources.credits import CreditsResource, AsyncCreditsResource from .resources.kfintech import KfintechResource, AsyncKfintechResource from .resources.cdsl.cdsl import CdslResource, AsyncCdslResource - from .resources.access_token import AccessTokenResource, AsyncAccessTokenResource - from .resources.verify_token import VerifyTokenResource, AsyncVerifyTokenResource from .resources.cams_kfintech import CamsKfintechResource, AsyncCamsKfintechResource from .resources.contract_note import ContractNoteResource, AsyncContractNoteResource @@ -154,30 +138,6 @@ def __init__( _strict_response_validation=_strict_response_validation, ) - @cached_property - def credits(self) -> CreditsResource: - from .resources.credits import CreditsResource - - return CreditsResource(self) - - @cached_property - def logs(self) -> LogsResource: - from .resources.logs import LogsResource - - return LogsResource(self) - - @cached_property - def access_token(self) -> AccessTokenResource: - from .resources.access_token import AccessTokenResource - - return AccessTokenResource(self) - - @cached_property - def verify_token(self) -> VerifyTokenResource: - from .resources.verify_token import VerifyTokenResource - - return VerifyTokenResource(self) - @cached_property def cams_kfintech(self) -> CamsKfintechResource: from .resources.cams_kfintech import CamsKfintechResource @@ -414,30 +374,6 @@ def __init__( _strict_response_validation=_strict_response_validation, ) - @cached_property - def credits(self) -> AsyncCreditsResource: - from .resources.credits import AsyncCreditsResource - - return AsyncCreditsResource(self) - - @cached_property - def logs(self) -> AsyncLogsResource: - from .resources.logs import AsyncLogsResource - - return AsyncLogsResource(self) - - @cached_property - def access_token(self) -> AsyncAccessTokenResource: - from .resources.access_token import AsyncAccessTokenResource - - return AsyncAccessTokenResource(self) - - @cached_property - def verify_token(self) -> AsyncVerifyTokenResource: - from .resources.verify_token import AsyncVerifyTokenResource - - return AsyncVerifyTokenResource(self) - @cached_property def cams_kfintech(self) -> AsyncCamsKfintechResource: from .resources.cams_kfintech import AsyncCamsKfintechResource @@ -601,30 +537,6 @@ class CasParserWithRawResponse: def __init__(self, client: CasParser) -> None: self._client = client - @cached_property - def credits(self) -> credits.CreditsResourceWithRawResponse: - from .resources.credits import CreditsResourceWithRawResponse - - return CreditsResourceWithRawResponse(self._client.credits) - - @cached_property - def logs(self) -> logs.LogsResourceWithRawResponse: - from .resources.logs import LogsResourceWithRawResponse - - return LogsResourceWithRawResponse(self._client.logs) - - @cached_property - def access_token(self) -> access_token.AccessTokenResourceWithRawResponse: - from .resources.access_token import AccessTokenResourceWithRawResponse - - return AccessTokenResourceWithRawResponse(self._client.access_token) - - @cached_property - def verify_token(self) -> verify_token.VerifyTokenResourceWithRawResponse: - from .resources.verify_token import VerifyTokenResourceWithRawResponse - - return VerifyTokenResourceWithRawResponse(self._client.verify_token) - @cached_property def cams_kfintech(self) -> cams_kfintech.CamsKfintechResourceWithRawResponse: from .resources.cams_kfintech import CamsKfintechResourceWithRawResponse @@ -674,30 +586,6 @@ class AsyncCasParserWithRawResponse: def __init__(self, client: AsyncCasParser) -> None: self._client = client - @cached_property - def credits(self) -> credits.AsyncCreditsResourceWithRawResponse: - from .resources.credits import AsyncCreditsResourceWithRawResponse - - return AsyncCreditsResourceWithRawResponse(self._client.credits) - - @cached_property - def logs(self) -> logs.AsyncLogsResourceWithRawResponse: - from .resources.logs import AsyncLogsResourceWithRawResponse - - return AsyncLogsResourceWithRawResponse(self._client.logs) - - @cached_property - def access_token(self) -> access_token.AsyncAccessTokenResourceWithRawResponse: - from .resources.access_token import AsyncAccessTokenResourceWithRawResponse - - return AsyncAccessTokenResourceWithRawResponse(self._client.access_token) - - @cached_property - def verify_token(self) -> verify_token.AsyncVerifyTokenResourceWithRawResponse: - from .resources.verify_token import AsyncVerifyTokenResourceWithRawResponse - - return AsyncVerifyTokenResourceWithRawResponse(self._client.verify_token) - @cached_property def cams_kfintech(self) -> cams_kfintech.AsyncCamsKfintechResourceWithRawResponse: from .resources.cams_kfintech import AsyncCamsKfintechResourceWithRawResponse @@ -747,30 +635,6 @@ class CasParserWithStreamedResponse: def __init__(self, client: CasParser) -> None: self._client = client - @cached_property - def credits(self) -> credits.CreditsResourceWithStreamingResponse: - from .resources.credits import CreditsResourceWithStreamingResponse - - return CreditsResourceWithStreamingResponse(self._client.credits) - - @cached_property - def logs(self) -> logs.LogsResourceWithStreamingResponse: - from .resources.logs import LogsResourceWithStreamingResponse - - return LogsResourceWithStreamingResponse(self._client.logs) - - @cached_property - def access_token(self) -> access_token.AccessTokenResourceWithStreamingResponse: - from .resources.access_token import AccessTokenResourceWithStreamingResponse - - return AccessTokenResourceWithStreamingResponse(self._client.access_token) - - @cached_property - def verify_token(self) -> verify_token.VerifyTokenResourceWithStreamingResponse: - from .resources.verify_token import VerifyTokenResourceWithStreamingResponse - - return VerifyTokenResourceWithStreamingResponse(self._client.verify_token) - @cached_property def cams_kfintech(self) -> cams_kfintech.CamsKfintechResourceWithStreamingResponse: from .resources.cams_kfintech import CamsKfintechResourceWithStreamingResponse @@ -820,30 +684,6 @@ class AsyncCasParserWithStreamedResponse: def __init__(self, client: AsyncCasParser) -> None: self._client = client - @cached_property - def credits(self) -> credits.AsyncCreditsResourceWithStreamingResponse: - from .resources.credits import AsyncCreditsResourceWithStreamingResponse - - return AsyncCreditsResourceWithStreamingResponse(self._client.credits) - - @cached_property - def logs(self) -> logs.AsyncLogsResourceWithStreamingResponse: - from .resources.logs import AsyncLogsResourceWithStreamingResponse - - return AsyncLogsResourceWithStreamingResponse(self._client.logs) - - @cached_property - def access_token(self) -> access_token.AsyncAccessTokenResourceWithStreamingResponse: - from .resources.access_token import AsyncAccessTokenResourceWithStreamingResponse - - return AsyncAccessTokenResourceWithStreamingResponse(self._client.access_token) - - @cached_property - def verify_token(self) -> verify_token.AsyncVerifyTokenResourceWithStreamingResponse: - from .resources.verify_token import AsyncVerifyTokenResourceWithStreamingResponse - - return AsyncVerifyTokenResourceWithStreamingResponse(self._client.verify_token) - @cached_property def cams_kfintech(self) -> cams_kfintech.AsyncCamsKfintechResourceWithStreamingResponse: from .resources.cams_kfintech import AsyncCamsKfintechResourceWithStreamingResponse diff --git a/src/cas_parser/resources/__init__.py b/src/cas_parser/resources/__init__.py index ac91596..4125404 100644 --- a/src/cas_parser/resources/__init__.py +++ b/src/cas_parser/resources/__init__.py @@ -8,14 +8,6 @@ CdslResourceWithStreamingResponse, AsyncCdslResourceWithStreamingResponse, ) -from .logs import ( - LogsResource, - AsyncLogsResource, - LogsResourceWithRawResponse, - AsyncLogsResourceWithRawResponse, - LogsResourceWithStreamingResponse, - AsyncLogsResourceWithStreamingResponse, -) from .nsdl import ( NsdlResource, AsyncNsdlResource, @@ -40,14 +32,6 @@ SmartResourceWithStreamingResponse, AsyncSmartResourceWithStreamingResponse, ) -from .credits import ( - CreditsResource, - AsyncCreditsResource, - CreditsResourceWithRawResponse, - AsyncCreditsResourceWithRawResponse, - CreditsResourceWithStreamingResponse, - AsyncCreditsResourceWithStreamingResponse, -) from .kfintech import ( KfintechResource, AsyncKfintechResource, @@ -56,22 +40,6 @@ KfintechResourceWithStreamingResponse, AsyncKfintechResourceWithStreamingResponse, ) -from .access_token import ( - AccessTokenResource, - AsyncAccessTokenResource, - AccessTokenResourceWithRawResponse, - AsyncAccessTokenResourceWithRawResponse, - AccessTokenResourceWithStreamingResponse, - AsyncAccessTokenResourceWithStreamingResponse, -) -from .verify_token import ( - VerifyTokenResource, - AsyncVerifyTokenResource, - VerifyTokenResourceWithRawResponse, - AsyncVerifyTokenResourceWithRawResponse, - VerifyTokenResourceWithStreamingResponse, - AsyncVerifyTokenResourceWithStreamingResponse, -) from .cams_kfintech import ( CamsKfintechResource, AsyncCamsKfintechResource, @@ -90,30 +58,6 @@ ) __all__ = [ - "CreditsResource", - "AsyncCreditsResource", - "CreditsResourceWithRawResponse", - "AsyncCreditsResourceWithRawResponse", - "CreditsResourceWithStreamingResponse", - "AsyncCreditsResourceWithStreamingResponse", - "LogsResource", - "AsyncLogsResource", - "LogsResourceWithRawResponse", - "AsyncLogsResourceWithRawResponse", - "LogsResourceWithStreamingResponse", - "AsyncLogsResourceWithStreamingResponse", - "AccessTokenResource", - "AsyncAccessTokenResource", - "AccessTokenResourceWithRawResponse", - "AsyncAccessTokenResourceWithRawResponse", - "AccessTokenResourceWithStreamingResponse", - "AsyncAccessTokenResourceWithStreamingResponse", - "VerifyTokenResource", - "AsyncVerifyTokenResource", - "VerifyTokenResourceWithRawResponse", - "AsyncVerifyTokenResourceWithRawResponse", - "VerifyTokenResourceWithStreamingResponse", - "AsyncVerifyTokenResourceWithStreamingResponse", "CamsKfintechResource", "AsyncCamsKfintechResource", "CamsKfintechResourceWithRawResponse", diff --git a/src/cas_parser/resources/access_token.py b/src/cas_parser/resources/access_token.py deleted file mode 100644 index aa92680..0000000 --- a/src/cas_parser/resources/access_token.py +++ /dev/null @@ -1,191 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import httpx - -from ..types import access_token_create_params -from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform -from .._compat import cached_property -from .._resource import SyncAPIResource, AsyncAPIResource -from .._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from .._base_client import make_request_options -from ..types.access_token_create_response import AccessTokenCreateResponse - -__all__ = ["AccessTokenResource", "AsyncAccessTokenResource"] - - -class AccessTokenResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> AccessTokenResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/CASParser/cas-parser-python#accessing-raw-response-data-eg-headers - """ - return AccessTokenResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AccessTokenResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/CASParser/cas-parser-python#with_streaming_response - """ - return AccessTokenResourceWithStreamingResponse(self) - - def create( - self, - *, - expiry_minutes: int | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AccessTokenCreateResponse: - """ - Generate a short-lived access token from your API key. - - **Use this endpoint from your backend** to create tokens that can be safely - passed to frontend/SDK. - - Access tokens: - - - Are prefixed with `at_` for easy identification - - Valid for up to 60 minutes - - Can be used in place of API keys on all v4 endpoints - - Cannot be used to generate other access tokens - - Args: - expiry_minutes: Token validity in minutes (max 60) - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._post( - "/v1/access-token", - body=maybe_transform( - {"expiry_minutes": expiry_minutes}, access_token_create_params.AccessTokenCreateParams - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=AccessTokenCreateResponse, - ) - - -class AsyncAccessTokenResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncAccessTokenResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/CASParser/cas-parser-python#accessing-raw-response-data-eg-headers - """ - return AsyncAccessTokenResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncAccessTokenResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/CASParser/cas-parser-python#with_streaming_response - """ - return AsyncAccessTokenResourceWithStreamingResponse(self) - - async def create( - self, - *, - expiry_minutes: int | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AccessTokenCreateResponse: - """ - Generate a short-lived access token from your API key. - - **Use this endpoint from your backend** to create tokens that can be safely - passed to frontend/SDK. - - Access tokens: - - - Are prefixed with `at_` for easy identification - - Valid for up to 60 minutes - - Can be used in place of API keys on all v4 endpoints - - Cannot be used to generate other access tokens - - Args: - expiry_minutes: Token validity in minutes (max 60) - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return await self._post( - "/v1/access-token", - body=await async_maybe_transform( - {"expiry_minutes": expiry_minutes}, access_token_create_params.AccessTokenCreateParams - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=AccessTokenCreateResponse, - ) - - -class AccessTokenResourceWithRawResponse: - def __init__(self, access_token: AccessTokenResource) -> None: - self._access_token = access_token - - self.create = to_raw_response_wrapper( - access_token.create, - ) - - -class AsyncAccessTokenResourceWithRawResponse: - def __init__(self, access_token: AsyncAccessTokenResource) -> None: - self._access_token = access_token - - self.create = async_to_raw_response_wrapper( - access_token.create, - ) - - -class AccessTokenResourceWithStreamingResponse: - def __init__(self, access_token: AccessTokenResource) -> None: - self._access_token = access_token - - self.create = to_streamed_response_wrapper( - access_token.create, - ) - - -class AsyncAccessTokenResourceWithStreamingResponse: - def __init__(self, access_token: AsyncAccessTokenResource) -> None: - self._access_token = access_token - - self.create = async_to_streamed_response_wrapper( - access_token.create, - ) diff --git a/src/cas_parser/resources/credits.py b/src/cas_parser/resources/credits.py deleted file mode 100644 index 4a86474..0000000 --- a/src/cas_parser/resources/credits.py +++ /dev/null @@ -1,155 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import httpx - -from .._types import Body, Query, Headers, NotGiven, not_given -from .._compat import cached_property -from .._resource import SyncAPIResource, AsyncAPIResource -from .._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from .._base_client import make_request_options -from ..types.credit_check_response import CreditCheckResponse - -__all__ = ["CreditsResource", "AsyncCreditsResource"] - - -class CreditsResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> CreditsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/CASParser/cas-parser-python#accessing-raw-response-data-eg-headers - """ - return CreditsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> CreditsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/CASParser/cas-parser-python#with_streaming_response - """ - return CreditsResourceWithStreamingResponse(self) - - def check( - self, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CreditCheckResponse: - """ - Check your remaining API credits and usage for the current billing period. - - Returns: - - - Number of API calls used and remaining credits - - Credit limit and reset date - - List of enabled features for your plan - - Credits reset at the start of each billing period. - """ - return self._post( - "/credits", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=CreditCheckResponse, - ) - - -class AsyncCreditsResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncCreditsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/CASParser/cas-parser-python#accessing-raw-response-data-eg-headers - """ - return AsyncCreditsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncCreditsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/CASParser/cas-parser-python#with_streaming_response - """ - return AsyncCreditsResourceWithStreamingResponse(self) - - async def check( - self, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CreditCheckResponse: - """ - Check your remaining API credits and usage for the current billing period. - - Returns: - - - Number of API calls used and remaining credits - - Credit limit and reset date - - List of enabled features for your plan - - Credits reset at the start of each billing period. - """ - return await self._post( - "/credits", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=CreditCheckResponse, - ) - - -class CreditsResourceWithRawResponse: - def __init__(self, credits: CreditsResource) -> None: - self._credits = credits - - self.check = to_raw_response_wrapper( - credits.check, - ) - - -class AsyncCreditsResourceWithRawResponse: - def __init__(self, credits: AsyncCreditsResource) -> None: - self._credits = credits - - self.check = async_to_raw_response_wrapper( - credits.check, - ) - - -class CreditsResourceWithStreamingResponse: - def __init__(self, credits: CreditsResource) -> None: - self._credits = credits - - self.check = to_streamed_response_wrapper( - credits.check, - ) - - -class AsyncCreditsResourceWithStreamingResponse: - def __init__(self, credits: AsyncCreditsResource) -> None: - self._credits = credits - - self.check = async_to_streamed_response_wrapper( - credits.check, - ) diff --git a/src/cas_parser/resources/logs.py b/src/cas_parser/resources/logs.py deleted file mode 100644 index bd6ec9b..0000000 --- a/src/cas_parser/resources/logs.py +++ /dev/null @@ -1,307 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Union -from datetime import datetime - -import httpx - -from ..types import log_create_params, log_get_summary_params -from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform -from .._compat import cached_property -from .._resource import SyncAPIResource, AsyncAPIResource -from .._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from .._base_client import make_request_options -from ..types.log_create_response import LogCreateResponse -from ..types.log_get_summary_response import LogGetSummaryResponse - -__all__ = ["LogsResource", "AsyncLogsResource"] - - -class LogsResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> LogsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/CASParser/cas-parser-python#accessing-raw-response-data-eg-headers - """ - return LogsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> LogsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/CASParser/cas-parser-python#with_streaming_response - """ - return LogsResourceWithStreamingResponse(self) - - def create( - self, - *, - end_time: Union[str, datetime] | Omit = omit, - limit: int | Omit = omit, - start_time: Union[str, datetime] | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> LogCreateResponse: - """ - Retrieve detailed API usage logs for your account. - - Returns a list of API calls with timestamps, features used, status codes, and - credits consumed. Useful for monitoring usage patterns and debugging. - - Args: - end_time: End time filter (ISO 8601). Defaults to now. - - limit: Maximum number of logs to return - - start_time: Start time filter (ISO 8601). Defaults to 30 days ago. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._post( - "/logs", - body=maybe_transform( - { - "end_time": end_time, - "limit": limit, - "start_time": start_time, - }, - log_create_params.LogCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=LogCreateResponse, - ) - - def get_summary( - self, - *, - end_time: Union[str, datetime] | Omit = omit, - start_time: Union[str, datetime] | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> LogGetSummaryResponse: - """ - Get aggregated usage statistics grouped by feature. - - Useful for understanding which API features are being used most and tracking - usage trends. - - Args: - end_time: End time filter (ISO 8601). Defaults to now. - - start_time: Start time filter (ISO 8601). Defaults to start of current month. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._post( - "/logs/summary", - body=maybe_transform( - { - "end_time": end_time, - "start_time": start_time, - }, - log_get_summary_params.LogGetSummaryParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=LogGetSummaryResponse, - ) - - -class AsyncLogsResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncLogsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/CASParser/cas-parser-python#accessing-raw-response-data-eg-headers - """ - return AsyncLogsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncLogsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/CASParser/cas-parser-python#with_streaming_response - """ - return AsyncLogsResourceWithStreamingResponse(self) - - async def create( - self, - *, - end_time: Union[str, datetime] | Omit = omit, - limit: int | Omit = omit, - start_time: Union[str, datetime] | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> LogCreateResponse: - """ - Retrieve detailed API usage logs for your account. - - Returns a list of API calls with timestamps, features used, status codes, and - credits consumed. Useful for monitoring usage patterns and debugging. - - Args: - end_time: End time filter (ISO 8601). Defaults to now. - - limit: Maximum number of logs to return - - start_time: Start time filter (ISO 8601). Defaults to 30 days ago. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return await self._post( - "/logs", - body=await async_maybe_transform( - { - "end_time": end_time, - "limit": limit, - "start_time": start_time, - }, - log_create_params.LogCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=LogCreateResponse, - ) - - async def get_summary( - self, - *, - end_time: Union[str, datetime] | Omit = omit, - start_time: Union[str, datetime] | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> LogGetSummaryResponse: - """ - Get aggregated usage statistics grouped by feature. - - Useful for understanding which API features are being used most and tracking - usage trends. - - Args: - end_time: End time filter (ISO 8601). Defaults to now. - - start_time: Start time filter (ISO 8601). Defaults to start of current month. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return await self._post( - "/logs/summary", - body=await async_maybe_transform( - { - "end_time": end_time, - "start_time": start_time, - }, - log_get_summary_params.LogGetSummaryParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=LogGetSummaryResponse, - ) - - -class LogsResourceWithRawResponse: - def __init__(self, logs: LogsResource) -> None: - self._logs = logs - - self.create = to_raw_response_wrapper( - logs.create, - ) - self.get_summary = to_raw_response_wrapper( - logs.get_summary, - ) - - -class AsyncLogsResourceWithRawResponse: - def __init__(self, logs: AsyncLogsResource) -> None: - self._logs = logs - - self.create = async_to_raw_response_wrapper( - logs.create, - ) - self.get_summary = async_to_raw_response_wrapper( - logs.get_summary, - ) - - -class LogsResourceWithStreamingResponse: - def __init__(self, logs: LogsResource) -> None: - self._logs = logs - - self.create = to_streamed_response_wrapper( - logs.create, - ) - self.get_summary = to_streamed_response_wrapper( - logs.get_summary, - ) - - -class AsyncLogsResourceWithStreamingResponse: - def __init__(self, logs: AsyncLogsResource) -> None: - self._logs = logs - - self.create = async_to_streamed_response_wrapper( - logs.create, - ) - self.get_summary = async_to_streamed_response_wrapper( - logs.get_summary, - ) diff --git a/src/cas_parser/resources/verify_token.py b/src/cas_parser/resources/verify_token.py deleted file mode 100644 index 273eb62..0000000 --- a/src/cas_parser/resources/verify_token.py +++ /dev/null @@ -1,143 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import httpx - -from .._types import Body, Query, Headers, NotGiven, not_given -from .._compat import cached_property -from .._resource import SyncAPIResource, AsyncAPIResource -from .._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from .._base_client import make_request_options -from ..types.verify_token_verify_response import VerifyTokenVerifyResponse - -__all__ = ["VerifyTokenResource", "AsyncVerifyTokenResource"] - - -class VerifyTokenResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> VerifyTokenResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/CASParser/cas-parser-python#accessing-raw-response-data-eg-headers - """ - return VerifyTokenResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> VerifyTokenResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/CASParser/cas-parser-python#with_streaming_response - """ - return VerifyTokenResourceWithStreamingResponse(self) - - def verify( - self, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> VerifyTokenVerifyResponse: - """Verify an access token and check if it's still valid. - - Useful for debugging token - issues. - """ - return self._post( - "/v1/verify-token", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=VerifyTokenVerifyResponse, - ) - - -class AsyncVerifyTokenResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncVerifyTokenResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/CASParser/cas-parser-python#accessing-raw-response-data-eg-headers - """ - return AsyncVerifyTokenResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncVerifyTokenResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/CASParser/cas-parser-python#with_streaming_response - """ - return AsyncVerifyTokenResourceWithStreamingResponse(self) - - async def verify( - self, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> VerifyTokenVerifyResponse: - """Verify an access token and check if it's still valid. - - Useful for debugging token - issues. - """ - return await self._post( - "/v1/verify-token", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=VerifyTokenVerifyResponse, - ) - - -class VerifyTokenResourceWithRawResponse: - def __init__(self, verify_token: VerifyTokenResource) -> None: - self._verify_token = verify_token - - self.verify = to_raw_response_wrapper( - verify_token.verify, - ) - - -class AsyncVerifyTokenResourceWithRawResponse: - def __init__(self, verify_token: AsyncVerifyTokenResource) -> None: - self._verify_token = verify_token - - self.verify = async_to_raw_response_wrapper( - verify_token.verify, - ) - - -class VerifyTokenResourceWithStreamingResponse: - def __init__(self, verify_token: VerifyTokenResource) -> None: - self._verify_token = verify_token - - self.verify = to_streamed_response_wrapper( - verify_token.verify, - ) - - -class AsyncVerifyTokenResourceWithStreamingResponse: - def __init__(self, verify_token: AsyncVerifyTokenResource) -> None: - self._verify_token = verify_token - - self.verify = async_to_streamed_response_wrapper( - verify_token.verify, - ) diff --git a/src/cas_parser/types/__init__.py b/src/cas_parser/types/__init__.py index d72939a..ee5666d 100644 --- a/src/cas_parser/types/__init__.py +++ b/src/cas_parser/types/__init__.py @@ -5,24 +5,16 @@ from .transaction import Transaction as Transaction from .linked_holder import LinkedHolder as LinkedHolder from .unified_response import UnifiedResponse as UnifiedResponse -from .log_create_params import LogCreateParams as LogCreateParams from .nsdl_parse_params import NsdlParseParams as NsdlParseParams -from .log_create_response import LogCreateResponse as LogCreateResponse from .cdsl_parse_pdf_params import CdslParsePdfParams as CdslParsePdfParams -from .credit_check_response import CreditCheckResponse as CreditCheckResponse -from .log_get_summary_params import LogGetSummaryParams as LogGetSummaryParams -from .log_get_summary_response import LogGetSummaryResponse as LogGetSummaryResponse -from .access_token_create_params import AccessTokenCreateParams as AccessTokenCreateParams from .cams_kfintech_parse_params import CamsKfintechParseParams as CamsKfintechParseParams from .contract_note_parse_params import ContractNoteParseParams as ContractNoteParseParams from .inbox_connect_email_params import InboxConnectEmailParams as InboxConnectEmailParams from .smart_parse_cas_pdf_params import SmartParseCasPdfParams as SmartParseCasPdfParams from .inbox_list_cas_files_params import InboxListCasFilesParams as InboxListCasFilesParams -from .access_token_create_response import AccessTokenCreateResponse as AccessTokenCreateResponse from .contract_note_parse_response import ContractNoteParseResponse as ContractNoteParseResponse from .inbox_connect_email_response import InboxConnectEmailResponse as InboxConnectEmailResponse from .kfintech_generate_cas_params import KfintechGenerateCasParams as KfintechGenerateCasParams -from .verify_token_verify_response import VerifyTokenVerifyResponse as VerifyTokenVerifyResponse from .inbox_list_cas_files_response import InboxListCasFilesResponse as InboxListCasFilesResponse from .kfintech_generate_cas_response import KfintechGenerateCasResponse as KfintechGenerateCasResponse from .inbox_disconnect_email_response import InboxDisconnectEmailResponse as InboxDisconnectEmailResponse diff --git a/src/cas_parser/types/access_token_create_params.py b/src/cas_parser/types/access_token_create_params.py deleted file mode 100644 index 1d3f392..0000000 --- a/src/cas_parser/types/access_token_create_params.py +++ /dev/null @@ -1,12 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import TypedDict - -__all__ = ["AccessTokenCreateParams"] - - -class AccessTokenCreateParams(TypedDict, total=False): - expiry_minutes: int - """Token validity in minutes (max 60)""" diff --git a/src/cas_parser/types/access_token_create_response.py b/src/cas_parser/types/access_token_create_response.py deleted file mode 100644 index 9a03c8c..0000000 --- a/src/cas_parser/types/access_token_create_response.py +++ /dev/null @@ -1,18 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Optional - -from .._models import BaseModel - -__all__ = ["AccessTokenCreateResponse"] - - -class AccessTokenCreateResponse(BaseModel): - access_token: Optional[str] = None - """The at\\__ prefixed access token""" - - expires_in: Optional[int] = None - """Token validity in seconds""" - - token_type: Optional[str] = None - """Always "api_key" - token is a drop-in replacement for x-api-key header""" diff --git a/src/cas_parser/types/credit_check_response.py b/src/cas_parser/types/credit_check_response.py deleted file mode 100644 index 9396b9f..0000000 --- a/src/cas_parser/types/credit_check_response.py +++ /dev/null @@ -1,28 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from datetime import datetime - -from .._models import BaseModel - -__all__ = ["CreditCheckResponse"] - - -class CreditCheckResponse(BaseModel): - enabled_features: Optional[List[str]] = None - """List of API features enabled for your plan""" - - is_unlimited: Optional[bool] = None - """Whether the account has unlimited credits""" - - limit: Optional[int] = None - """Total credit limit for billing period""" - - remaining: Optional[float] = None - """Remaining credits (null if unlimited)""" - - resets_at: Optional[datetime] = None - """When credits reset (ISO 8601)""" - - used: Optional[float] = None - """Number of credits used this billing period""" diff --git a/src/cas_parser/types/log_create_params.py b/src/cas_parser/types/log_create_params.py deleted file mode 100644 index 6104297..0000000 --- a/src/cas_parser/types/log_create_params.py +++ /dev/null @@ -1,22 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Union -from datetime import datetime -from typing_extensions import Annotated, TypedDict - -from .._utils import PropertyInfo - -__all__ = ["LogCreateParams"] - - -class LogCreateParams(TypedDict, total=False): - end_time: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] - """End time filter (ISO 8601). Defaults to now.""" - - limit: int - """Maximum number of logs to return""" - - start_time: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] - """Start time filter (ISO 8601). Defaults to 30 days ago.""" diff --git a/src/cas_parser/types/log_create_response.py b/src/cas_parser/types/log_create_response.py deleted file mode 100644 index 446d6e5..0000000 --- a/src/cas_parser/types/log_create_response.py +++ /dev/null @@ -1,37 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from datetime import datetime - -from .._models import BaseModel - -__all__ = ["LogCreateResponse", "Log"] - - -class Log(BaseModel): - credits: Optional[float] = None - """Credits consumed for this request""" - - feature: Optional[str] = None - """API feature used""" - - path: Optional[str] = None - """API endpoint path""" - - request_id: Optional[str] = None - """Unique request identifier""" - - status_code: Optional[int] = None - """HTTP response status code""" - - timestamp: Optional[datetime] = None - """When the request was made""" - - -class LogCreateResponse(BaseModel): - count: Optional[int] = None - """Number of logs returned""" - - logs: Optional[List[Log]] = None - - status: Optional[str] = None diff --git a/src/cas_parser/types/log_get_summary_params.py b/src/cas_parser/types/log_get_summary_params.py deleted file mode 100644 index fc9ffe7..0000000 --- a/src/cas_parser/types/log_get_summary_params.py +++ /dev/null @@ -1,19 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Union -from datetime import datetime -from typing_extensions import Annotated, TypedDict - -from .._utils import PropertyInfo - -__all__ = ["LogGetSummaryParams"] - - -class LogGetSummaryParams(TypedDict, total=False): - end_time: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] - """End time filter (ISO 8601). Defaults to now.""" - - start_time: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] - """Start time filter (ISO 8601). Defaults to start of current month.""" diff --git a/src/cas_parser/types/log_get_summary_response.py b/src/cas_parser/types/log_get_summary_response.py deleted file mode 100644 index d947f84..0000000 --- a/src/cas_parser/types/log_get_summary_response.py +++ /dev/null @@ -1,35 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional - -from .._models import BaseModel - -__all__ = ["LogGetSummaryResponse", "Summary", "SummaryByFeature"] - - -class SummaryByFeature(BaseModel): - credits: Optional[float] = None - """Credits consumed by this feature""" - - feature: Optional[str] = None - """API feature name""" - - requests: Optional[int] = None - """Number of requests for this feature""" - - -class Summary(BaseModel): - by_feature: Optional[List[SummaryByFeature]] = None - """Usage breakdown by feature""" - - total_credits: Optional[float] = None - """Total credits consumed in the period""" - - total_requests: Optional[int] = None - """Total API requests made in the period""" - - -class LogGetSummaryResponse(BaseModel): - status: Optional[str] = None - - summary: Optional[Summary] = None diff --git a/src/cas_parser/types/verify_token_verify_response.py b/src/cas_parser/types/verify_token_verify_response.py deleted file mode 100644 index fcfebe7..0000000 --- a/src/cas_parser/types/verify_token_verify_response.py +++ /dev/null @@ -1,18 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Optional - -from .._models import BaseModel - -__all__ = ["VerifyTokenVerifyResponse"] - - -class VerifyTokenVerifyResponse(BaseModel): - error: Optional[str] = None - """Error message (only shown if invalid)""" - - masked_api_key: Optional[str] = None - """Masked API key (only shown if valid)""" - - valid: Optional[bool] = None - """Whether the token is valid""" diff --git a/tests/api_resources/test_access_token.py b/tests/api_resources/test_access_token.py deleted file mode 100644 index 32d63c9..0000000 --- a/tests/api_resources/test_access_token.py +++ /dev/null @@ -1,96 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from cas_parser import CasParser, AsyncCasParser -from tests.utils import assert_matches_type -from cas_parser.types import AccessTokenCreateResponse - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestAccessToken: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_create(self, client: CasParser) -> None: - access_token = client.access_token.create() - assert_matches_type(AccessTokenCreateResponse, access_token, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_create_with_all_params(self, client: CasParser) -> None: - access_token = client.access_token.create( - expiry_minutes=60, - ) - assert_matches_type(AccessTokenCreateResponse, access_token, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_create(self, client: CasParser) -> None: - response = client.access_token.with_raw_response.create() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - access_token = response.parse() - assert_matches_type(AccessTokenCreateResponse, access_token, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_create(self, client: CasParser) -> None: - with client.access_token.with_streaming_response.create() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - access_token = response.parse() - assert_matches_type(AccessTokenCreateResponse, access_token, path=["response"]) - - assert cast(Any, response.is_closed) is True - - -class TestAsyncAccessToken: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_create(self, async_client: AsyncCasParser) -> None: - access_token = await async_client.access_token.create() - assert_matches_type(AccessTokenCreateResponse, access_token, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_create_with_all_params(self, async_client: AsyncCasParser) -> None: - access_token = await async_client.access_token.create( - expiry_minutes=60, - ) - assert_matches_type(AccessTokenCreateResponse, access_token, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_create(self, async_client: AsyncCasParser) -> None: - response = await async_client.access_token.with_raw_response.create() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - access_token = await response.parse() - assert_matches_type(AccessTokenCreateResponse, access_token, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_create(self, async_client: AsyncCasParser) -> None: - async with async_client.access_token.with_streaming_response.create() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - access_token = await response.parse() - assert_matches_type(AccessTokenCreateResponse, access_token, path=["response"]) - - assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_credits.py b/tests/api_resources/test_credits.py deleted file mode 100644 index 8538889..0000000 --- a/tests/api_resources/test_credits.py +++ /dev/null @@ -1,80 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from cas_parser import CasParser, AsyncCasParser -from tests.utils import assert_matches_type -from cas_parser.types import CreditCheckResponse - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestCredits: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_check(self, client: CasParser) -> None: - credit = client.credits.check() - assert_matches_type(CreditCheckResponse, credit, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_check(self, client: CasParser) -> None: - response = client.credits.with_raw_response.check() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - credit = response.parse() - assert_matches_type(CreditCheckResponse, credit, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_check(self, client: CasParser) -> None: - with client.credits.with_streaming_response.check() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - credit = response.parse() - assert_matches_type(CreditCheckResponse, credit, path=["response"]) - - assert cast(Any, response.is_closed) is True - - -class TestAsyncCredits: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_check(self, async_client: AsyncCasParser) -> None: - credit = await async_client.credits.check() - assert_matches_type(CreditCheckResponse, credit, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_check(self, async_client: AsyncCasParser) -> None: - response = await async_client.credits.with_raw_response.check() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - credit = await response.parse() - assert_matches_type(CreditCheckResponse, credit, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_check(self, async_client: AsyncCasParser) -> None: - async with async_client.credits.with_streaming_response.check() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - credit = await response.parse() - assert_matches_type(CreditCheckResponse, credit, path=["response"]) - - assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_logs.py b/tests/api_resources/test_logs.py deleted file mode 100644 index 43908ef..0000000 --- a/tests/api_resources/test_logs.py +++ /dev/null @@ -1,175 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from cas_parser import CasParser, AsyncCasParser -from tests.utils import assert_matches_type -from cas_parser.types import LogCreateResponse, LogGetSummaryResponse -from cas_parser._utils import parse_datetime - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestLogs: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_create(self, client: CasParser) -> None: - log = client.logs.create() - assert_matches_type(LogCreateResponse, log, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_create_with_all_params(self, client: CasParser) -> None: - log = client.logs.create( - end_time=parse_datetime("2026-01-31T23:59:59Z"), - limit=1, - start_time=parse_datetime("2026-01-01T00:00:00Z"), - ) - assert_matches_type(LogCreateResponse, log, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_create(self, client: CasParser) -> None: - response = client.logs.with_raw_response.create() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - log = response.parse() - assert_matches_type(LogCreateResponse, log, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_create(self, client: CasParser) -> None: - with client.logs.with_streaming_response.create() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - log = response.parse() - assert_matches_type(LogCreateResponse, log, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_get_summary(self, client: CasParser) -> None: - log = client.logs.get_summary() - assert_matches_type(LogGetSummaryResponse, log, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_get_summary_with_all_params(self, client: CasParser) -> None: - log = client.logs.get_summary( - end_time=parse_datetime("2019-12-27T18:11:19.117Z"), - start_time=parse_datetime("2019-12-27T18:11:19.117Z"), - ) - assert_matches_type(LogGetSummaryResponse, log, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_get_summary(self, client: CasParser) -> None: - response = client.logs.with_raw_response.get_summary() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - log = response.parse() - assert_matches_type(LogGetSummaryResponse, log, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_get_summary(self, client: CasParser) -> None: - with client.logs.with_streaming_response.get_summary() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - log = response.parse() - assert_matches_type(LogGetSummaryResponse, log, path=["response"]) - - assert cast(Any, response.is_closed) is True - - -class TestAsyncLogs: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_create(self, async_client: AsyncCasParser) -> None: - log = await async_client.logs.create() - assert_matches_type(LogCreateResponse, log, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_create_with_all_params(self, async_client: AsyncCasParser) -> None: - log = await async_client.logs.create( - end_time=parse_datetime("2026-01-31T23:59:59Z"), - limit=1, - start_time=parse_datetime("2026-01-01T00:00:00Z"), - ) - assert_matches_type(LogCreateResponse, log, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_create(self, async_client: AsyncCasParser) -> None: - response = await async_client.logs.with_raw_response.create() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - log = await response.parse() - assert_matches_type(LogCreateResponse, log, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_create(self, async_client: AsyncCasParser) -> None: - async with async_client.logs.with_streaming_response.create() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - log = await response.parse() - assert_matches_type(LogCreateResponse, log, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_get_summary(self, async_client: AsyncCasParser) -> None: - log = await async_client.logs.get_summary() - assert_matches_type(LogGetSummaryResponse, log, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_get_summary_with_all_params(self, async_client: AsyncCasParser) -> None: - log = await async_client.logs.get_summary( - end_time=parse_datetime("2019-12-27T18:11:19.117Z"), - start_time=parse_datetime("2019-12-27T18:11:19.117Z"), - ) - assert_matches_type(LogGetSummaryResponse, log, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_get_summary(self, async_client: AsyncCasParser) -> None: - response = await async_client.logs.with_raw_response.get_summary() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - log = await response.parse() - assert_matches_type(LogGetSummaryResponse, log, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_get_summary(self, async_client: AsyncCasParser) -> None: - async with async_client.logs.with_streaming_response.get_summary() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - log = await response.parse() - assert_matches_type(LogGetSummaryResponse, log, path=["response"]) - - assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_verify_token.py b/tests/api_resources/test_verify_token.py deleted file mode 100644 index 43e594d..0000000 --- a/tests/api_resources/test_verify_token.py +++ /dev/null @@ -1,80 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from cas_parser import CasParser, AsyncCasParser -from tests.utils import assert_matches_type -from cas_parser.types import VerifyTokenVerifyResponse - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestVerifyToken: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_verify(self, client: CasParser) -> None: - verify_token = client.verify_token.verify() - assert_matches_type(VerifyTokenVerifyResponse, verify_token, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_verify(self, client: CasParser) -> None: - response = client.verify_token.with_raw_response.verify() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - verify_token = response.parse() - assert_matches_type(VerifyTokenVerifyResponse, verify_token, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_verify(self, client: CasParser) -> None: - with client.verify_token.with_streaming_response.verify() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - verify_token = response.parse() - assert_matches_type(VerifyTokenVerifyResponse, verify_token, path=["response"]) - - assert cast(Any, response.is_closed) is True - - -class TestAsyncVerifyToken: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_verify(self, async_client: AsyncCasParser) -> None: - verify_token = await async_client.verify_token.verify() - assert_matches_type(VerifyTokenVerifyResponse, verify_token, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_verify(self, async_client: AsyncCasParser) -> None: - response = await async_client.verify_token.with_raw_response.verify() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - verify_token = await response.parse() - assert_matches_type(VerifyTokenVerifyResponse, verify_token, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_verify(self, async_client: AsyncCasParser) -> None: - async with async_client.verify_token.with_streaming_response.verify() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - verify_token = await response.parse() - assert_matches_type(VerifyTokenVerifyResponse, verify_token, path=["response"]) - - assert cast(Any, response.is_closed) is True diff --git a/tests/test_client.py b/tests/test_client.py index ef1fd91..ed6cfac 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -863,20 +863,20 @@ def test_parse_retry_after_header( @mock.patch("cas_parser._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, client: CasParser) -> None: - respx_mock.post("/credits").mock(side_effect=httpx.TimeoutException("Test timeout error")) + respx_mock.post("/v4/cams_kfintech/parse").mock(side_effect=httpx.TimeoutException("Test timeout error")) with pytest.raises(APITimeoutError): - client.credits.with_streaming_response.check().__enter__() + client.cams_kfintech.with_streaming_response.parse().__enter__() assert _get_open_connections(client) == 0 @mock.patch("cas_parser._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client: CasParser) -> None: - respx_mock.post("/credits").mock(return_value=httpx.Response(500)) + respx_mock.post("/v4/cams_kfintech/parse").mock(return_value=httpx.Response(500)) with pytest.raises(APIStatusError): - client.credits.with_streaming_response.check().__enter__() + client.cams_kfintech.with_streaming_response.parse().__enter__() assert _get_open_connections(client) == 0 @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @@ -903,9 +903,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: return httpx.Response(500) return httpx.Response(200) - respx_mock.post("/credits").mock(side_effect=retry_handler) + respx_mock.post("/v4/cams_kfintech/parse").mock(side_effect=retry_handler) - response = client.credits.with_raw_response.check() + response = client.cams_kfintech.with_raw_response.parse() assert response.retries_taken == failures_before_success assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success @@ -927,9 +927,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: return httpx.Response(500) return httpx.Response(200) - respx_mock.post("/credits").mock(side_effect=retry_handler) + respx_mock.post("/v4/cams_kfintech/parse").mock(side_effect=retry_handler) - response = client.credits.with_raw_response.check(extra_headers={"x-stainless-retry-count": Omit()}) + response = client.cams_kfintech.with_raw_response.parse(extra_headers={"x-stainless-retry-count": Omit()}) assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0 @@ -950,9 +950,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: return httpx.Response(500) return httpx.Response(200) - respx_mock.post("/credits").mock(side_effect=retry_handler) + respx_mock.post("/v4/cams_kfintech/parse").mock(side_effect=retry_handler) - response = client.credits.with_raw_response.check(extra_headers={"x-stainless-retry-count": "42"}) + response = client.cams_kfintech.with_raw_response.parse(extra_headers={"x-stainless-retry-count": "42"}) assert response.http_request.headers.get("x-stainless-retry-count") == "42" @@ -1775,10 +1775,10 @@ async def test_parse_retry_after_header( async def test_retrying_timeout_errors_doesnt_leak( self, respx_mock: MockRouter, async_client: AsyncCasParser ) -> None: - respx_mock.post("/credits").mock(side_effect=httpx.TimeoutException("Test timeout error")) + respx_mock.post("/v4/cams_kfintech/parse").mock(side_effect=httpx.TimeoutException("Test timeout error")) with pytest.raises(APITimeoutError): - await async_client.credits.with_streaming_response.check().__aenter__() + await async_client.cams_kfintech.with_streaming_response.parse().__aenter__() assert _get_open_connections(async_client) == 0 @@ -1787,10 +1787,10 @@ async def test_retrying_timeout_errors_doesnt_leak( async def test_retrying_status_errors_doesnt_leak( self, respx_mock: MockRouter, async_client: AsyncCasParser ) -> None: - respx_mock.post("/credits").mock(return_value=httpx.Response(500)) + respx_mock.post("/v4/cams_kfintech/parse").mock(return_value=httpx.Response(500)) with pytest.raises(APIStatusError): - await async_client.credits.with_streaming_response.check().__aenter__() + await async_client.cams_kfintech.with_streaming_response.parse().__aenter__() assert _get_open_connections(async_client) == 0 @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @@ -1817,9 +1817,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: return httpx.Response(500) return httpx.Response(200) - respx_mock.post("/credits").mock(side_effect=retry_handler) + respx_mock.post("/v4/cams_kfintech/parse").mock(side_effect=retry_handler) - response = await client.credits.with_raw_response.check() + response = await client.cams_kfintech.with_raw_response.parse() assert response.retries_taken == failures_before_success assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success @@ -1841,9 +1841,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: return httpx.Response(500) return httpx.Response(200) - respx_mock.post("/credits").mock(side_effect=retry_handler) + respx_mock.post("/v4/cams_kfintech/parse").mock(side_effect=retry_handler) - response = await client.credits.with_raw_response.check(extra_headers={"x-stainless-retry-count": Omit()}) + response = await client.cams_kfintech.with_raw_response.parse(extra_headers={"x-stainless-retry-count": Omit()}) assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0 @@ -1864,9 +1864,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: return httpx.Response(500) return httpx.Response(200) - respx_mock.post("/credits").mock(side_effect=retry_handler) + respx_mock.post("/v4/cams_kfintech/parse").mock(side_effect=retry_handler) - response = await client.credits.with_raw_response.check(extra_headers={"x-stainless-retry-count": "42"}) + response = await client.cams_kfintech.with_raw_response.parse(extra_headers={"x-stainless-retry-count": "42"}) assert response.http_request.headers.get("x-stainless-retry-count") == "42" From 478ce0c2535de083e5c6f9248d0df77e6bafb410 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sun, 22 Feb 2026 23:17:54 +0000 Subject: [PATCH 2/6] feat(api): api update --- .stats.yml | 4 ++-- src/cas_parser/types/inbox_list_cas_files_response.py | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 80a6900..1e5b8d1 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 12 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-6a9d3b677dcfb856dc571865c34b3fe401e4d7f0d799edfc743acb9a55800bd0.yml -openapi_spec_hash: 037703a6c741e4310fda3f57c22fa51e +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-e6762e83ef7cdff129d03d0ab8c130db2fb5d1d820142847c27d72b40a0e9f53.yml +openapi_spec_hash: f38fb40a2b28bae4b0c9c4228c1c0e0d config_hash: 41c337f5cda03b13880617490f82bad0 diff --git a/src/cas_parser/types/inbox_list_cas_files_response.py b/src/cas_parser/types/inbox_list_cas_files_response.py index ef27d92..686944a 100644 --- a/src/cas_parser/types/inbox_list_cas_files_response.py +++ b/src/cas_parser/types/inbox_list_cas_files_response.py @@ -30,6 +30,9 @@ class File(BaseModel): original_filename: Optional[str] = None """Original attachment filename from the email""" + sender_email: Optional[str] = None + """Email address of the CAS authority who sent this""" + size: Optional[int] = None """File size in bytes""" From 8a5eeaa3334343c0a5e8268d06c0c25d7dfdef00 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 00:17:44 +0000 Subject: [PATCH 3/6] feat(api): api update --- .stats.yml | 4 ++-- src/cas_parser/types/inbox_list_cas_files_response.py | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index 1e5b8d1..b880d0c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 12 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-e6762e83ef7cdff129d03d0ab8c130db2fb5d1d820142847c27d72b40a0e9f53.yml -openapi_spec_hash: f38fb40a2b28bae4b0c9c4228c1c0e0d +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-d9763d006969b49a1473851069fdfa429eb13133b64103a62963bb70ddb22305.yml +openapi_spec_hash: 6aee689b7a759b12c85c088c15e29bc0 config_hash: 41c337f5cda03b13880617490f82bad0 diff --git a/src/cas_parser/types/inbox_list_cas_files_response.py b/src/cas_parser/types/inbox_list_cas_files_response.py index 686944a..25b960f 100644 --- a/src/cas_parser/types/inbox_list_cas_files_response.py +++ b/src/cas_parser/types/inbox_list_cas_files_response.py @@ -31,7 +31,10 @@ class File(BaseModel): """Original attachment filename from the email""" sender_email: Optional[str] = None - """Email address of the CAS authority who sent this""" + """ + Email address of the CAS authority (CDSL, NSDL, CAMS, or KFintech) who + originally sent this statement + """ size: Optional[int] = None """File size in bytes""" From a4d6336829387e982ac938935252129ff5131f65 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 02:53:25 +0000 Subject: [PATCH 4/6] feat(api): manual updates --- .stats.yml | 4 +- README.md | 26 +- api.md | 69 +++ src/cas_parser/_client.py | 200 ++++++- src/cas_parser/resources/__init__.py | 70 +++ src/cas_parser/resources/access_token.py | 195 ++++++ src/cas_parser/resources/credits.py | 155 +++++ src/cas_parser/resources/inbound_email.py | 563 ++++++++++++++++++ src/cas_parser/resources/logs.py | 315 ++++++++++ src/cas_parser/resources/verify_token.py | 143 +++++ src/cas_parser/types/__init__.py | 14 + .../types/access_token_create_params.py | 12 + .../types/access_token_create_response.py | 18 + src/cas_parser/types/credit_check_response.py | 28 + .../types/inbound_email_create_params.py | 47 ++ .../types/inbound_email_create_response.py | 40 ++ .../types/inbound_email_delete_response.py | 13 + .../types/inbound_email_list_params.py | 18 + .../types/inbound_email_list_response.py | 53 ++ .../types/inbound_email_retrieve_response.py | 40 ++ src/cas_parser/types/log_create_params.py | 22 + src/cas_parser/types/log_create_response.py | 37 ++ .../types/log_get_summary_params.py | 19 + .../types/log_get_summary_response.py | 35 ++ .../types/verify_token_verify_response.py | 18 + tests/api_resources/test_access_token.py | 96 +++ tests/api_resources/test_credits.py | 80 +++ tests/api_resources/test_inbound_email.py | 371 ++++++++++++ tests/api_resources/test_logs.py | 175 ++++++ tests/api_resources/test_verify_token.py | 80 +++ tests/test_client.py | 40 +- 31 files changed, 2960 insertions(+), 36 deletions(-) create mode 100644 src/cas_parser/resources/access_token.py create mode 100644 src/cas_parser/resources/credits.py create mode 100644 src/cas_parser/resources/inbound_email.py create mode 100644 src/cas_parser/resources/logs.py create mode 100644 src/cas_parser/resources/verify_token.py create mode 100644 src/cas_parser/types/access_token_create_params.py create mode 100644 src/cas_parser/types/access_token_create_response.py create mode 100644 src/cas_parser/types/credit_check_response.py create mode 100644 src/cas_parser/types/inbound_email_create_params.py create mode 100644 src/cas_parser/types/inbound_email_create_response.py create mode 100644 src/cas_parser/types/inbound_email_delete_response.py create mode 100644 src/cas_parser/types/inbound_email_list_params.py create mode 100644 src/cas_parser/types/inbound_email_list_response.py create mode 100644 src/cas_parser/types/inbound_email_retrieve_response.py create mode 100644 src/cas_parser/types/log_create_params.py create mode 100644 src/cas_parser/types/log_create_response.py create mode 100644 src/cas_parser/types/log_get_summary_params.py create mode 100644 src/cas_parser/types/log_get_summary_response.py create mode 100644 src/cas_parser/types/verify_token_verify_response.py create mode 100644 tests/api_resources/test_access_token.py create mode 100644 tests/api_resources/test_credits.py create mode 100644 tests/api_resources/test_inbound_email.py create mode 100644 tests/api_resources/test_logs.py create mode 100644 tests/api_resources/test_verify_token.py diff --git a/.stats.yml b/.stats.yml index b880d0c..cdf3c0a 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 12 +configured_endpoints: 21 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-d9763d006969b49a1473851069fdfa429eb13133b64103a62963bb70ddb22305.yml openapi_spec_hash: 6aee689b7a759b12c85c088c15e29bc0 -config_hash: 41c337f5cda03b13880617490f82bad0 +config_hash: d54f39abb185904495bef7c5f8702746 diff --git a/README.md b/README.md index 04c0f3e..f7b645a 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,8 @@ client = CasParser( environment="environment_1", ) -unified_response = client.cams_kfintech.parse() -print(unified_response.demat_accounts) +response = client.credits.check() +print(response.enabled_features) ``` While you can provide an `api_key` keyword argument, @@ -69,8 +69,8 @@ client = AsyncCasParser( async def main() -> None: - unified_response = await client.cams_kfintech.parse() - print(unified_response.demat_accounts) + response = await client.credits.check() + print(response.enabled_features) asyncio.run(main()) @@ -103,8 +103,8 @@ async def main() -> None: api_key=os.environ.get("CAS_PARSER_API_KEY"), # This is the default and can be omitted http_client=DefaultAioHttpClient(), ) as client: - unified_response = await client.cams_kfintech.parse() - print(unified_response.demat_accounts) + response = await client.credits.check() + print(response.enabled_features) asyncio.run(main()) @@ -135,7 +135,7 @@ from cas_parser import CasParser client = CasParser() try: - client.cams_kfintech.parse() + client.credits.check() except cas_parser.APIConnectionError as e: print("The server could not be reached") print(e.__cause__) # an underlying Exception, likely raised within httpx. @@ -178,7 +178,7 @@ client = CasParser( ) # Or, configure per-request: -client.with_options(max_retries=5).cams_kfintech.parse() +client.with_options(max_retries=5).credits.check() ``` ### Timeouts @@ -201,7 +201,7 @@ client = CasParser( ) # Override per-request: -client.with_options(timeout=5.0).cams_kfintech.parse() +client.with_options(timeout=5.0).credits.check() ``` On timeout, an `APITimeoutError` is thrown. @@ -242,11 +242,11 @@ The "raw" Response object can be accessed by prefixing `.with_raw_response.` to from cas_parser import CasParser client = CasParser() -response = client.cams_kfintech.with_raw_response.parse() +response = client.credits.with_raw_response.check() print(response.headers.get('X-My-Header')) -cams_kfintech = response.parse() # get the object that `cams_kfintech.parse()` would have returned -print(cams_kfintech.demat_accounts) +credit = response.parse() # get the object that `credits.check()` would have returned +print(credit.enabled_features) ``` These methods return an [`APIResponse`](https://github.com/CASParser/cas-parser-python/tree/main/src/cas_parser/_response.py) object. @@ -260,7 +260,7 @@ The above interface eagerly reads the full response body when you make the reque To stream the response body, use `.with_streaming_response` instead, which requires a context manager and only reads the response body once you call `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` or `.parse()`. In the async client, these are async methods. ```python -with client.cams_kfintech.with_streaming_response.parse() as response: +with client.credits.with_streaming_response.check() as response: print(response.headers.get("X-My-Header")) for line in response.iter_lines(): diff --git a/api.md b/api.md index 8ba2d2c..164b61d 100644 --- a/api.md +++ b/api.md @@ -1,3 +1,52 @@ +# Credits + +Types: + +```python +from cas_parser.types import CreditCheckResponse +``` + +Methods: + +- client.credits.check() -> CreditCheckResponse + +# Logs + +Types: + +```python +from cas_parser.types import LogCreateResponse, LogGetSummaryResponse +``` + +Methods: + +- client.logs.create(\*\*params) -> LogCreateResponse +- client.logs.get_summary(\*\*params) -> LogGetSummaryResponse + +# AccessToken + +Types: + +```python +from cas_parser.types import AccessTokenCreateResponse +``` + +Methods: + +- client.access_token.create(\*\*params) -> AccessTokenCreateResponse + +# VerifyToken + +Types: + +```python +from cas_parser.types import VerifyTokenVerifyResponse +``` + +Methods: + +- client.verify_token.verify() -> VerifyTokenVerifyResponse + # CamsKfintech Types: @@ -84,3 +133,23 @@ Methods: Methods: - client.smart.parse_cas_pdf(\*\*params) -> UnifiedResponse + +# InboundEmail + +Types: + +```python +from cas_parser.types import ( + InboundEmailCreateResponse, + InboundEmailRetrieveResponse, + InboundEmailListResponse, + InboundEmailDeleteResponse, +) +``` + +Methods: + +- client.inbound_email.create(\*\*params) -> InboundEmailCreateResponse +- client.inbound_email.retrieve(inbound_email_id) -> InboundEmailRetrieveResponse +- client.inbound_email.list(\*\*params) -> InboundEmailListResponse +- client.inbound_email.delete(inbound_email_id) -> InboundEmailDeleteResponse diff --git a/src/cas_parser/_client.py b/src/cas_parser/_client.py index 8041bb8..e63f97f 100644 --- a/src/cas_parser/_client.py +++ b/src/cas_parser/_client.py @@ -31,14 +31,32 @@ ) if TYPE_CHECKING: - from .resources import cdsl, nsdl, inbox, smart, kfintech, cams_kfintech, contract_note + from .resources import ( + cdsl, + logs, + nsdl, + inbox, + smart, + credits, + kfintech, + access_token, + verify_token, + cams_kfintech, + contract_note, + inbound_email, + ) + from .resources.logs import LogsResource, AsyncLogsResource from .resources.nsdl import NsdlResource, AsyncNsdlResource from .resources.inbox import InboxResource, AsyncInboxResource from .resources.smart import SmartResource, AsyncSmartResource + from .resources.credits import CreditsResource, AsyncCreditsResource from .resources.kfintech import KfintechResource, AsyncKfintechResource from .resources.cdsl.cdsl import CdslResource, AsyncCdslResource + from .resources.access_token import AccessTokenResource, AsyncAccessTokenResource + from .resources.verify_token import VerifyTokenResource, AsyncVerifyTokenResource from .resources.cams_kfintech import CamsKfintechResource, AsyncCamsKfintechResource from .resources.contract_note import ContractNoteResource, AsyncContractNoteResource + from .resources.inbound_email import InboundEmailResource, AsyncInboundEmailResource __all__ = [ "ENVIRONMENTS", @@ -138,6 +156,30 @@ def __init__( _strict_response_validation=_strict_response_validation, ) + @cached_property + def credits(self) -> CreditsResource: + from .resources.credits import CreditsResource + + return CreditsResource(self) + + @cached_property + def logs(self) -> LogsResource: + from .resources.logs import LogsResource + + return LogsResource(self) + + @cached_property + def access_token(self) -> AccessTokenResource: + from .resources.access_token import AccessTokenResource + + return AccessTokenResource(self) + + @cached_property + def verify_token(self) -> VerifyTokenResource: + from .resources.verify_token import VerifyTokenResource + + return VerifyTokenResource(self) + @cached_property def cams_kfintech(self) -> CamsKfintechResource: from .resources.cams_kfintech import CamsKfintechResource @@ -180,6 +222,12 @@ def smart(self) -> SmartResource: return SmartResource(self) + @cached_property + def inbound_email(self) -> InboundEmailResource: + from .resources.inbound_email import InboundEmailResource + + return InboundEmailResource(self) + @cached_property def with_raw_response(self) -> CasParserWithRawResponse: return CasParserWithRawResponse(self) @@ -374,6 +422,30 @@ def __init__( _strict_response_validation=_strict_response_validation, ) + @cached_property + def credits(self) -> AsyncCreditsResource: + from .resources.credits import AsyncCreditsResource + + return AsyncCreditsResource(self) + + @cached_property + def logs(self) -> AsyncLogsResource: + from .resources.logs import AsyncLogsResource + + return AsyncLogsResource(self) + + @cached_property + def access_token(self) -> AsyncAccessTokenResource: + from .resources.access_token import AsyncAccessTokenResource + + return AsyncAccessTokenResource(self) + + @cached_property + def verify_token(self) -> AsyncVerifyTokenResource: + from .resources.verify_token import AsyncVerifyTokenResource + + return AsyncVerifyTokenResource(self) + @cached_property def cams_kfintech(self) -> AsyncCamsKfintechResource: from .resources.cams_kfintech import AsyncCamsKfintechResource @@ -416,6 +488,12 @@ def smart(self) -> AsyncSmartResource: return AsyncSmartResource(self) + @cached_property + def inbound_email(self) -> AsyncInboundEmailResource: + from .resources.inbound_email import AsyncInboundEmailResource + + return AsyncInboundEmailResource(self) + @cached_property def with_raw_response(self) -> AsyncCasParserWithRawResponse: return AsyncCasParserWithRawResponse(self) @@ -537,6 +615,30 @@ class CasParserWithRawResponse: def __init__(self, client: CasParser) -> None: self._client = client + @cached_property + def credits(self) -> credits.CreditsResourceWithRawResponse: + from .resources.credits import CreditsResourceWithRawResponse + + return CreditsResourceWithRawResponse(self._client.credits) + + @cached_property + def logs(self) -> logs.LogsResourceWithRawResponse: + from .resources.logs import LogsResourceWithRawResponse + + return LogsResourceWithRawResponse(self._client.logs) + + @cached_property + def access_token(self) -> access_token.AccessTokenResourceWithRawResponse: + from .resources.access_token import AccessTokenResourceWithRawResponse + + return AccessTokenResourceWithRawResponse(self._client.access_token) + + @cached_property + def verify_token(self) -> verify_token.VerifyTokenResourceWithRawResponse: + from .resources.verify_token import VerifyTokenResourceWithRawResponse + + return VerifyTokenResourceWithRawResponse(self._client.verify_token) + @cached_property def cams_kfintech(self) -> cams_kfintech.CamsKfintechResourceWithRawResponse: from .resources.cams_kfintech import CamsKfintechResourceWithRawResponse @@ -579,6 +681,12 @@ def smart(self) -> smart.SmartResourceWithRawResponse: return SmartResourceWithRawResponse(self._client.smart) + @cached_property + def inbound_email(self) -> inbound_email.InboundEmailResourceWithRawResponse: + from .resources.inbound_email import InboundEmailResourceWithRawResponse + + return InboundEmailResourceWithRawResponse(self._client.inbound_email) + class AsyncCasParserWithRawResponse: _client: AsyncCasParser @@ -586,6 +694,30 @@ class AsyncCasParserWithRawResponse: def __init__(self, client: AsyncCasParser) -> None: self._client = client + @cached_property + def credits(self) -> credits.AsyncCreditsResourceWithRawResponse: + from .resources.credits import AsyncCreditsResourceWithRawResponse + + return AsyncCreditsResourceWithRawResponse(self._client.credits) + + @cached_property + def logs(self) -> logs.AsyncLogsResourceWithRawResponse: + from .resources.logs import AsyncLogsResourceWithRawResponse + + return AsyncLogsResourceWithRawResponse(self._client.logs) + + @cached_property + def access_token(self) -> access_token.AsyncAccessTokenResourceWithRawResponse: + from .resources.access_token import AsyncAccessTokenResourceWithRawResponse + + return AsyncAccessTokenResourceWithRawResponse(self._client.access_token) + + @cached_property + def verify_token(self) -> verify_token.AsyncVerifyTokenResourceWithRawResponse: + from .resources.verify_token import AsyncVerifyTokenResourceWithRawResponse + + return AsyncVerifyTokenResourceWithRawResponse(self._client.verify_token) + @cached_property def cams_kfintech(self) -> cams_kfintech.AsyncCamsKfintechResourceWithRawResponse: from .resources.cams_kfintech import AsyncCamsKfintechResourceWithRawResponse @@ -628,6 +760,12 @@ def smart(self) -> smart.AsyncSmartResourceWithRawResponse: return AsyncSmartResourceWithRawResponse(self._client.smart) + @cached_property + def inbound_email(self) -> inbound_email.AsyncInboundEmailResourceWithRawResponse: + from .resources.inbound_email import AsyncInboundEmailResourceWithRawResponse + + return AsyncInboundEmailResourceWithRawResponse(self._client.inbound_email) + class CasParserWithStreamedResponse: _client: CasParser @@ -635,6 +773,30 @@ class CasParserWithStreamedResponse: def __init__(self, client: CasParser) -> None: self._client = client + @cached_property + def credits(self) -> credits.CreditsResourceWithStreamingResponse: + from .resources.credits import CreditsResourceWithStreamingResponse + + return CreditsResourceWithStreamingResponse(self._client.credits) + + @cached_property + def logs(self) -> logs.LogsResourceWithStreamingResponse: + from .resources.logs import LogsResourceWithStreamingResponse + + return LogsResourceWithStreamingResponse(self._client.logs) + + @cached_property + def access_token(self) -> access_token.AccessTokenResourceWithStreamingResponse: + from .resources.access_token import AccessTokenResourceWithStreamingResponse + + return AccessTokenResourceWithStreamingResponse(self._client.access_token) + + @cached_property + def verify_token(self) -> verify_token.VerifyTokenResourceWithStreamingResponse: + from .resources.verify_token import VerifyTokenResourceWithStreamingResponse + + return VerifyTokenResourceWithStreamingResponse(self._client.verify_token) + @cached_property def cams_kfintech(self) -> cams_kfintech.CamsKfintechResourceWithStreamingResponse: from .resources.cams_kfintech import CamsKfintechResourceWithStreamingResponse @@ -677,6 +839,12 @@ def smart(self) -> smart.SmartResourceWithStreamingResponse: return SmartResourceWithStreamingResponse(self._client.smart) + @cached_property + def inbound_email(self) -> inbound_email.InboundEmailResourceWithStreamingResponse: + from .resources.inbound_email import InboundEmailResourceWithStreamingResponse + + return InboundEmailResourceWithStreamingResponse(self._client.inbound_email) + class AsyncCasParserWithStreamedResponse: _client: AsyncCasParser @@ -684,6 +852,30 @@ class AsyncCasParserWithStreamedResponse: def __init__(self, client: AsyncCasParser) -> None: self._client = client + @cached_property + def credits(self) -> credits.AsyncCreditsResourceWithStreamingResponse: + from .resources.credits import AsyncCreditsResourceWithStreamingResponse + + return AsyncCreditsResourceWithStreamingResponse(self._client.credits) + + @cached_property + def logs(self) -> logs.AsyncLogsResourceWithStreamingResponse: + from .resources.logs import AsyncLogsResourceWithStreamingResponse + + return AsyncLogsResourceWithStreamingResponse(self._client.logs) + + @cached_property + def access_token(self) -> access_token.AsyncAccessTokenResourceWithStreamingResponse: + from .resources.access_token import AsyncAccessTokenResourceWithStreamingResponse + + return AsyncAccessTokenResourceWithStreamingResponse(self._client.access_token) + + @cached_property + def verify_token(self) -> verify_token.AsyncVerifyTokenResourceWithStreamingResponse: + from .resources.verify_token import AsyncVerifyTokenResourceWithStreamingResponse + + return AsyncVerifyTokenResourceWithStreamingResponse(self._client.verify_token) + @cached_property def cams_kfintech(self) -> cams_kfintech.AsyncCamsKfintechResourceWithStreamingResponse: from .resources.cams_kfintech import AsyncCamsKfintechResourceWithStreamingResponse @@ -726,6 +918,12 @@ def smart(self) -> smart.AsyncSmartResourceWithStreamingResponse: return AsyncSmartResourceWithStreamingResponse(self._client.smart) + @cached_property + def inbound_email(self) -> inbound_email.AsyncInboundEmailResourceWithStreamingResponse: + from .resources.inbound_email import AsyncInboundEmailResourceWithStreamingResponse + + return AsyncInboundEmailResourceWithStreamingResponse(self._client.inbound_email) + Client = CasParser diff --git a/src/cas_parser/resources/__init__.py b/src/cas_parser/resources/__init__.py index 4125404..34f05f7 100644 --- a/src/cas_parser/resources/__init__.py +++ b/src/cas_parser/resources/__init__.py @@ -8,6 +8,14 @@ CdslResourceWithStreamingResponse, AsyncCdslResourceWithStreamingResponse, ) +from .logs import ( + LogsResource, + AsyncLogsResource, + LogsResourceWithRawResponse, + AsyncLogsResourceWithRawResponse, + LogsResourceWithStreamingResponse, + AsyncLogsResourceWithStreamingResponse, +) from .nsdl import ( NsdlResource, AsyncNsdlResource, @@ -32,6 +40,14 @@ SmartResourceWithStreamingResponse, AsyncSmartResourceWithStreamingResponse, ) +from .credits import ( + CreditsResource, + AsyncCreditsResource, + CreditsResourceWithRawResponse, + AsyncCreditsResourceWithRawResponse, + CreditsResourceWithStreamingResponse, + AsyncCreditsResourceWithStreamingResponse, +) from .kfintech import ( KfintechResource, AsyncKfintechResource, @@ -40,6 +56,22 @@ KfintechResourceWithStreamingResponse, AsyncKfintechResourceWithStreamingResponse, ) +from .access_token import ( + AccessTokenResource, + AsyncAccessTokenResource, + AccessTokenResourceWithRawResponse, + AsyncAccessTokenResourceWithRawResponse, + AccessTokenResourceWithStreamingResponse, + AsyncAccessTokenResourceWithStreamingResponse, +) +from .verify_token import ( + VerifyTokenResource, + AsyncVerifyTokenResource, + VerifyTokenResourceWithRawResponse, + AsyncVerifyTokenResourceWithRawResponse, + VerifyTokenResourceWithStreamingResponse, + AsyncVerifyTokenResourceWithStreamingResponse, +) from .cams_kfintech import ( CamsKfintechResource, AsyncCamsKfintechResource, @@ -56,8 +88,40 @@ ContractNoteResourceWithStreamingResponse, AsyncContractNoteResourceWithStreamingResponse, ) +from .inbound_email import ( + InboundEmailResource, + AsyncInboundEmailResource, + InboundEmailResourceWithRawResponse, + AsyncInboundEmailResourceWithRawResponse, + InboundEmailResourceWithStreamingResponse, + AsyncInboundEmailResourceWithStreamingResponse, +) __all__ = [ + "CreditsResource", + "AsyncCreditsResource", + "CreditsResourceWithRawResponse", + "AsyncCreditsResourceWithRawResponse", + "CreditsResourceWithStreamingResponse", + "AsyncCreditsResourceWithStreamingResponse", + "LogsResource", + "AsyncLogsResource", + "LogsResourceWithRawResponse", + "AsyncLogsResourceWithRawResponse", + "LogsResourceWithStreamingResponse", + "AsyncLogsResourceWithStreamingResponse", + "AccessTokenResource", + "AsyncAccessTokenResource", + "AccessTokenResourceWithRawResponse", + "AsyncAccessTokenResourceWithRawResponse", + "AccessTokenResourceWithStreamingResponse", + "AsyncAccessTokenResourceWithStreamingResponse", + "VerifyTokenResource", + "AsyncVerifyTokenResource", + "VerifyTokenResourceWithRawResponse", + "AsyncVerifyTokenResourceWithRawResponse", + "VerifyTokenResourceWithStreamingResponse", + "AsyncVerifyTokenResourceWithStreamingResponse", "CamsKfintechResource", "AsyncCamsKfintechResource", "CamsKfintechResourceWithRawResponse", @@ -100,4 +164,10 @@ "AsyncSmartResourceWithRawResponse", "SmartResourceWithStreamingResponse", "AsyncSmartResourceWithStreamingResponse", + "InboundEmailResource", + "AsyncInboundEmailResource", + "InboundEmailResourceWithRawResponse", + "AsyncInboundEmailResourceWithRawResponse", + "InboundEmailResourceWithStreamingResponse", + "AsyncInboundEmailResourceWithStreamingResponse", ] diff --git a/src/cas_parser/resources/access_token.py b/src/cas_parser/resources/access_token.py new file mode 100644 index 0000000..bfda93b --- /dev/null +++ b/src/cas_parser/resources/access_token.py @@ -0,0 +1,195 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ..types import access_token_create_params +from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from .._utils import maybe_transform, async_maybe_transform +from .._compat import cached_property +from .._resource import SyncAPIResource, AsyncAPIResource +from .._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from .._base_client import make_request_options +from ..types.access_token_create_response import AccessTokenCreateResponse + +__all__ = ["AccessTokenResource", "AsyncAccessTokenResource"] + + +class AccessTokenResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> AccessTokenResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/CASParser/cas-parser-python#accessing-raw-response-data-eg-headers + """ + return AccessTokenResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AccessTokenResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/CASParser/cas-parser-python#with_streaming_response + """ + return AccessTokenResourceWithStreamingResponse(self) + + def create( + self, + *, + expiry_minutes: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AccessTokenCreateResponse: + """ + Generate a short-lived access token from your API key. + + **Use this endpoint from your backend** to create tokens that can be safely + passed to frontend/SDK. + + **Legacy path:** `/v1/access-token` (still supported) + + Access tokens: + + - Are prefixed with `at_` for easy identification + - Valid for up to 60 minutes + - Can be used in place of API keys on all v4 endpoints + - Cannot be used to generate other access tokens + + Args: + expiry_minutes: Token validity in minutes (max 60) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/v1/token", + body=maybe_transform( + {"expiry_minutes": expiry_minutes}, access_token_create_params.AccessTokenCreateParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AccessTokenCreateResponse, + ) + + +class AsyncAccessTokenResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncAccessTokenResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/CASParser/cas-parser-python#accessing-raw-response-data-eg-headers + """ + return AsyncAccessTokenResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncAccessTokenResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/CASParser/cas-parser-python#with_streaming_response + """ + return AsyncAccessTokenResourceWithStreamingResponse(self) + + async def create( + self, + *, + expiry_minutes: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AccessTokenCreateResponse: + """ + Generate a short-lived access token from your API key. + + **Use this endpoint from your backend** to create tokens that can be safely + passed to frontend/SDK. + + **Legacy path:** `/v1/access-token` (still supported) + + Access tokens: + + - Are prefixed with `at_` for easy identification + - Valid for up to 60 minutes + - Can be used in place of API keys on all v4 endpoints + - Cannot be used to generate other access tokens + + Args: + expiry_minutes: Token validity in minutes (max 60) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/v1/token", + body=await async_maybe_transform( + {"expiry_minutes": expiry_minutes}, access_token_create_params.AccessTokenCreateParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AccessTokenCreateResponse, + ) + + +class AccessTokenResourceWithRawResponse: + def __init__(self, access_token: AccessTokenResource) -> None: + self._access_token = access_token + + self.create = to_raw_response_wrapper( + access_token.create, + ) + + +class AsyncAccessTokenResourceWithRawResponse: + def __init__(self, access_token: AsyncAccessTokenResource) -> None: + self._access_token = access_token + + self.create = async_to_raw_response_wrapper( + access_token.create, + ) + + +class AccessTokenResourceWithStreamingResponse: + def __init__(self, access_token: AccessTokenResource) -> None: + self._access_token = access_token + + self.create = to_streamed_response_wrapper( + access_token.create, + ) + + +class AsyncAccessTokenResourceWithStreamingResponse: + def __init__(self, access_token: AsyncAccessTokenResource) -> None: + self._access_token = access_token + + self.create = async_to_streamed_response_wrapper( + access_token.create, + ) diff --git a/src/cas_parser/resources/credits.py b/src/cas_parser/resources/credits.py new file mode 100644 index 0000000..264693d --- /dev/null +++ b/src/cas_parser/resources/credits.py @@ -0,0 +1,155 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from .._types import Body, Query, Headers, NotGiven, not_given +from .._compat import cached_property +from .._resource import SyncAPIResource, AsyncAPIResource +from .._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from .._base_client import make_request_options +from ..types.credit_check_response import CreditCheckResponse + +__all__ = ["CreditsResource", "AsyncCreditsResource"] + + +class CreditsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> CreditsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/CASParser/cas-parser-python#accessing-raw-response-data-eg-headers + """ + return CreditsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> CreditsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/CASParser/cas-parser-python#with_streaming_response + """ + return CreditsResourceWithStreamingResponse(self) + + def check( + self, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> CreditCheckResponse: + """ + Check your remaining API credits and usage for the current billing period. + + Returns: + + - Number of API calls used and remaining credits + - Credit limit and reset date + - List of enabled features for your plan + + Credits reset at the start of each billing period. + """ + return self._post( + "/v1/credits", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=CreditCheckResponse, + ) + + +class AsyncCreditsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncCreditsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/CASParser/cas-parser-python#accessing-raw-response-data-eg-headers + """ + return AsyncCreditsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncCreditsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/CASParser/cas-parser-python#with_streaming_response + """ + return AsyncCreditsResourceWithStreamingResponse(self) + + async def check( + self, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> CreditCheckResponse: + """ + Check your remaining API credits and usage for the current billing period. + + Returns: + + - Number of API calls used and remaining credits + - Credit limit and reset date + - List of enabled features for your plan + + Credits reset at the start of each billing period. + """ + return await self._post( + "/v1/credits", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=CreditCheckResponse, + ) + + +class CreditsResourceWithRawResponse: + def __init__(self, credits: CreditsResource) -> None: + self._credits = credits + + self.check = to_raw_response_wrapper( + credits.check, + ) + + +class AsyncCreditsResourceWithRawResponse: + def __init__(self, credits: AsyncCreditsResource) -> None: + self._credits = credits + + self.check = async_to_raw_response_wrapper( + credits.check, + ) + + +class CreditsResourceWithStreamingResponse: + def __init__(self, credits: CreditsResource) -> None: + self._credits = credits + + self.check = to_streamed_response_wrapper( + credits.check, + ) + + +class AsyncCreditsResourceWithStreamingResponse: + def __init__(self, credits: AsyncCreditsResource) -> None: + self._credits = credits + + self.check = async_to_streamed_response_wrapper( + credits.check, + ) diff --git a/src/cas_parser/resources/inbound_email.py b/src/cas_parser/resources/inbound_email.py new file mode 100644 index 0000000..e20ae7b --- /dev/null +++ b/src/cas_parser/resources/inbound_email.py @@ -0,0 +1,563 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, List +from typing_extensions import Literal + +import httpx + +from ..types import inbound_email_list_params, inbound_email_create_params +from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from .._utils import maybe_transform, async_maybe_transform +from .._compat import cached_property +from .._resource import SyncAPIResource, AsyncAPIResource +from .._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from .._base_client import make_request_options +from ..types.inbound_email_list_response import InboundEmailListResponse +from ..types.inbound_email_create_response import InboundEmailCreateResponse +from ..types.inbound_email_delete_response import InboundEmailDeleteResponse +from ..types.inbound_email_retrieve_response import InboundEmailRetrieveResponse + +__all__ = ["InboundEmailResource", "AsyncInboundEmailResource"] + + +class InboundEmailResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> InboundEmailResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/CASParser/cas-parser-python#accessing-raw-response-data-eg-headers + """ + return InboundEmailResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> InboundEmailResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/CASParser/cas-parser-python#with_streaming_response + """ + return InboundEmailResourceWithStreamingResponse(self) + + def create( + self, + *, + callback_url: str, + alias: str | Omit = omit, + allowed_sources: List[Literal["cdsl", "nsdl", "cams", "kfintech"]] | Omit = omit, + metadata: Dict[str, str] | Omit = omit, + reference: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> InboundEmailCreateResponse: + """ + Create a dedicated inbound email address for collecting CAS statements via email + forwarding. + + **How it works:** + + 1. Create an inbound email with your webhook URL + 2. Display the email address to your user (e.g., "Forward your CAS to + ie_xxx@import.casparser.in") + 3. When an investor forwards a CAS email, we verify the sender and deliver to + your webhook + + **Webhook Delivery:** + + - We POST to your `callback_url` with JSON body containing files (matching + EmailCASFile schema) + - Failed deliveries are retried automatically with exponential backoff + + **Inactivity:** + + - Inbound emails with no activity in 30 days are marked inactive + - Active inbound emails remain operational indefinitely + + Args: + callback_url: Webhook URL where we POST email notifications. Must be HTTPS in production (HTTP + allowed for localhost during development). + + alias: Optional custom email prefix for user-friendly addresses. + + - Must be 3-32 characters + - Alphanumeric + hyphens only + - Must start and end with letter/number + - Example: `john-portfolio@import.casparser.in` + - If omitted, generates random ID like `ie_abc123xyz@import.casparser.in` + + allowed_sources: Filter emails by CAS provider. If omitted, accepts all providers. + + - `cdsl` → eCAS@cdslstatement.com + - `nsdl` → NSDL-CAS@nsdl.co.in + - `cams` → donotreply@camsonline.com + - `kfintech` → samfS@kfintech.com + + metadata: Optional key-value pairs (max 10) to include in webhook payload. Useful for + passing context like plan_type, campaign_id, etc. + + reference: Your internal identifier (e.g., user_id, account_id). Returned in webhook + payload for correlation. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/v4/inbound-email", + body=maybe_transform( + { + "callback_url": callback_url, + "alias": alias, + "allowed_sources": allowed_sources, + "metadata": metadata, + "reference": reference, + }, + inbound_email_create_params.InboundEmailCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=InboundEmailCreateResponse, + ) + + def retrieve( + self, + inbound_email_id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> InboundEmailRetrieveResponse: + """ + Retrieve details of a specific mailbox including statistics. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not inbound_email_id: + raise ValueError(f"Expected a non-empty value for `inbound_email_id` but received {inbound_email_id!r}") + return self._get( + f"/v4/inbound-email/{inbound_email_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=InboundEmailRetrieveResponse, + ) + + def list( + self, + *, + limit: int | Omit = omit, + offset: int | Omit = omit, + status: Literal["active", "paused", "all"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> InboundEmailListResponse: + """List all mailboxes associated with your API key. + + Returns active and inactive + mailboxes (deleted mailboxes are excluded). + + Args: + limit: Maximum number of inbound emails to return + + offset: Pagination offset + + status: Filter by status + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get( + "/v4/inbound-email", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "limit": limit, + "offset": offset, + "status": status, + }, + inbound_email_list_params.InboundEmailListParams, + ), + ), + cast_to=InboundEmailListResponse, + ) + + def delete( + self, + inbound_email_id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> InboundEmailDeleteResponse: + """Permanently delete an inbound email address. + + It will stop accepting emails. + + **Note:** Deletion is immediate and cannot be undone. Any emails received after + deletion will be rejected. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not inbound_email_id: + raise ValueError(f"Expected a non-empty value for `inbound_email_id` but received {inbound_email_id!r}") + return self._delete( + f"/v4/inbound-email/{inbound_email_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=InboundEmailDeleteResponse, + ) + + +class AsyncInboundEmailResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncInboundEmailResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/CASParser/cas-parser-python#accessing-raw-response-data-eg-headers + """ + return AsyncInboundEmailResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncInboundEmailResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/CASParser/cas-parser-python#with_streaming_response + """ + return AsyncInboundEmailResourceWithStreamingResponse(self) + + async def create( + self, + *, + callback_url: str, + alias: str | Omit = omit, + allowed_sources: List[Literal["cdsl", "nsdl", "cams", "kfintech"]] | Omit = omit, + metadata: Dict[str, str] | Omit = omit, + reference: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> InboundEmailCreateResponse: + """ + Create a dedicated inbound email address for collecting CAS statements via email + forwarding. + + **How it works:** + + 1. Create an inbound email with your webhook URL + 2. Display the email address to your user (e.g., "Forward your CAS to + ie_xxx@import.casparser.in") + 3. When an investor forwards a CAS email, we verify the sender and deliver to + your webhook + + **Webhook Delivery:** + + - We POST to your `callback_url` with JSON body containing files (matching + EmailCASFile schema) + - Failed deliveries are retried automatically with exponential backoff + + **Inactivity:** + + - Inbound emails with no activity in 30 days are marked inactive + - Active inbound emails remain operational indefinitely + + Args: + callback_url: Webhook URL where we POST email notifications. Must be HTTPS in production (HTTP + allowed for localhost during development). + + alias: Optional custom email prefix for user-friendly addresses. + + - Must be 3-32 characters + - Alphanumeric + hyphens only + - Must start and end with letter/number + - Example: `john-portfolio@import.casparser.in` + - If omitted, generates random ID like `ie_abc123xyz@import.casparser.in` + + allowed_sources: Filter emails by CAS provider. If omitted, accepts all providers. + + - `cdsl` → eCAS@cdslstatement.com + - `nsdl` → NSDL-CAS@nsdl.co.in + - `cams` → donotreply@camsonline.com + - `kfintech` → samfS@kfintech.com + + metadata: Optional key-value pairs (max 10) to include in webhook payload. Useful for + passing context like plan_type, campaign_id, etc. + + reference: Your internal identifier (e.g., user_id, account_id). Returned in webhook + payload for correlation. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/v4/inbound-email", + body=await async_maybe_transform( + { + "callback_url": callback_url, + "alias": alias, + "allowed_sources": allowed_sources, + "metadata": metadata, + "reference": reference, + }, + inbound_email_create_params.InboundEmailCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=InboundEmailCreateResponse, + ) + + async def retrieve( + self, + inbound_email_id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> InboundEmailRetrieveResponse: + """ + Retrieve details of a specific mailbox including statistics. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not inbound_email_id: + raise ValueError(f"Expected a non-empty value for `inbound_email_id` but received {inbound_email_id!r}") + return await self._get( + f"/v4/inbound-email/{inbound_email_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=InboundEmailRetrieveResponse, + ) + + async def list( + self, + *, + limit: int | Omit = omit, + offset: int | Omit = omit, + status: Literal["active", "paused", "all"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> InboundEmailListResponse: + """List all mailboxes associated with your API key. + + Returns active and inactive + mailboxes (deleted mailboxes are excluded). + + Args: + limit: Maximum number of inbound emails to return + + offset: Pagination offset + + status: Filter by status + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._get( + "/v4/inbound-email", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "limit": limit, + "offset": offset, + "status": status, + }, + inbound_email_list_params.InboundEmailListParams, + ), + ), + cast_to=InboundEmailListResponse, + ) + + async def delete( + self, + inbound_email_id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> InboundEmailDeleteResponse: + """Permanently delete an inbound email address. + + It will stop accepting emails. + + **Note:** Deletion is immediate and cannot be undone. Any emails received after + deletion will be rejected. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not inbound_email_id: + raise ValueError(f"Expected a non-empty value for `inbound_email_id` but received {inbound_email_id!r}") + return await self._delete( + f"/v4/inbound-email/{inbound_email_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=InboundEmailDeleteResponse, + ) + + +class InboundEmailResourceWithRawResponse: + def __init__(self, inbound_email: InboundEmailResource) -> None: + self._inbound_email = inbound_email + + self.create = to_raw_response_wrapper( + inbound_email.create, + ) + self.retrieve = to_raw_response_wrapper( + inbound_email.retrieve, + ) + self.list = to_raw_response_wrapper( + inbound_email.list, + ) + self.delete = to_raw_response_wrapper( + inbound_email.delete, + ) + + +class AsyncInboundEmailResourceWithRawResponse: + def __init__(self, inbound_email: AsyncInboundEmailResource) -> None: + self._inbound_email = inbound_email + + self.create = async_to_raw_response_wrapper( + inbound_email.create, + ) + self.retrieve = async_to_raw_response_wrapper( + inbound_email.retrieve, + ) + self.list = async_to_raw_response_wrapper( + inbound_email.list, + ) + self.delete = async_to_raw_response_wrapper( + inbound_email.delete, + ) + + +class InboundEmailResourceWithStreamingResponse: + def __init__(self, inbound_email: InboundEmailResource) -> None: + self._inbound_email = inbound_email + + self.create = to_streamed_response_wrapper( + inbound_email.create, + ) + self.retrieve = to_streamed_response_wrapper( + inbound_email.retrieve, + ) + self.list = to_streamed_response_wrapper( + inbound_email.list, + ) + self.delete = to_streamed_response_wrapper( + inbound_email.delete, + ) + + +class AsyncInboundEmailResourceWithStreamingResponse: + def __init__(self, inbound_email: AsyncInboundEmailResource) -> None: + self._inbound_email = inbound_email + + self.create = async_to_streamed_response_wrapper( + inbound_email.create, + ) + self.retrieve = async_to_streamed_response_wrapper( + inbound_email.retrieve, + ) + self.list = async_to_streamed_response_wrapper( + inbound_email.list, + ) + self.delete = async_to_streamed_response_wrapper( + inbound_email.delete, + ) diff --git a/src/cas_parser/resources/logs.py b/src/cas_parser/resources/logs.py new file mode 100644 index 0000000..45ba056 --- /dev/null +++ b/src/cas_parser/resources/logs.py @@ -0,0 +1,315 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from datetime import datetime + +import httpx + +from ..types import log_create_params, log_get_summary_params +from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from .._utils import maybe_transform, async_maybe_transform +from .._compat import cached_property +from .._resource import SyncAPIResource, AsyncAPIResource +from .._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from .._base_client import make_request_options +from ..types.log_create_response import LogCreateResponse +from ..types.log_get_summary_response import LogGetSummaryResponse + +__all__ = ["LogsResource", "AsyncLogsResource"] + + +class LogsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> LogsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/CASParser/cas-parser-python#accessing-raw-response-data-eg-headers + """ + return LogsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> LogsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/CASParser/cas-parser-python#with_streaming_response + """ + return LogsResourceWithStreamingResponse(self) + + def create( + self, + *, + end_time: Union[str, datetime] | Omit = omit, + limit: int | Omit = omit, + start_time: Union[str, datetime] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> LogCreateResponse: + """ + Retrieve detailed API usage logs for your account. + + Returns a list of API calls with timestamps, features used, status codes, and + credits consumed. Useful for monitoring usage patterns and debugging. + + **Legacy path:** `/logs` (still supported) + + Args: + end_time: End time filter (ISO 8601). Defaults to now. + + limit: Maximum number of logs to return + + start_time: Start time filter (ISO 8601). Defaults to 30 days ago. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/v1/usage", + body=maybe_transform( + { + "end_time": end_time, + "limit": limit, + "start_time": start_time, + }, + log_create_params.LogCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=LogCreateResponse, + ) + + def get_summary( + self, + *, + end_time: Union[str, datetime] | Omit = omit, + start_time: Union[str, datetime] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> LogGetSummaryResponse: + """ + Get aggregated usage statistics grouped by feature. + + Useful for understanding which API features are being used most and tracking + usage trends. + + **Legacy path:** `/logs/summary` (still supported) + + Args: + end_time: End time filter (ISO 8601). Defaults to now. + + start_time: Start time filter (ISO 8601). Defaults to start of current month. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/v1/usage/summary", + body=maybe_transform( + { + "end_time": end_time, + "start_time": start_time, + }, + log_get_summary_params.LogGetSummaryParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=LogGetSummaryResponse, + ) + + +class AsyncLogsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncLogsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/CASParser/cas-parser-python#accessing-raw-response-data-eg-headers + """ + return AsyncLogsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncLogsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/CASParser/cas-parser-python#with_streaming_response + """ + return AsyncLogsResourceWithStreamingResponse(self) + + async def create( + self, + *, + end_time: Union[str, datetime] | Omit = omit, + limit: int | Omit = omit, + start_time: Union[str, datetime] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> LogCreateResponse: + """ + Retrieve detailed API usage logs for your account. + + Returns a list of API calls with timestamps, features used, status codes, and + credits consumed. Useful for monitoring usage patterns and debugging. + + **Legacy path:** `/logs` (still supported) + + Args: + end_time: End time filter (ISO 8601). Defaults to now. + + limit: Maximum number of logs to return + + start_time: Start time filter (ISO 8601). Defaults to 30 days ago. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/v1/usage", + body=await async_maybe_transform( + { + "end_time": end_time, + "limit": limit, + "start_time": start_time, + }, + log_create_params.LogCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=LogCreateResponse, + ) + + async def get_summary( + self, + *, + end_time: Union[str, datetime] | Omit = omit, + start_time: Union[str, datetime] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> LogGetSummaryResponse: + """ + Get aggregated usage statistics grouped by feature. + + Useful for understanding which API features are being used most and tracking + usage trends. + + **Legacy path:** `/logs/summary` (still supported) + + Args: + end_time: End time filter (ISO 8601). Defaults to now. + + start_time: Start time filter (ISO 8601). Defaults to start of current month. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/v1/usage/summary", + body=await async_maybe_transform( + { + "end_time": end_time, + "start_time": start_time, + }, + log_get_summary_params.LogGetSummaryParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=LogGetSummaryResponse, + ) + + +class LogsResourceWithRawResponse: + def __init__(self, logs: LogsResource) -> None: + self._logs = logs + + self.create = to_raw_response_wrapper( + logs.create, + ) + self.get_summary = to_raw_response_wrapper( + logs.get_summary, + ) + + +class AsyncLogsResourceWithRawResponse: + def __init__(self, logs: AsyncLogsResource) -> None: + self._logs = logs + + self.create = async_to_raw_response_wrapper( + logs.create, + ) + self.get_summary = async_to_raw_response_wrapper( + logs.get_summary, + ) + + +class LogsResourceWithStreamingResponse: + def __init__(self, logs: LogsResource) -> None: + self._logs = logs + + self.create = to_streamed_response_wrapper( + logs.create, + ) + self.get_summary = to_streamed_response_wrapper( + logs.get_summary, + ) + + +class AsyncLogsResourceWithStreamingResponse: + def __init__(self, logs: AsyncLogsResource) -> None: + self._logs = logs + + self.create = async_to_streamed_response_wrapper( + logs.create, + ) + self.get_summary = async_to_streamed_response_wrapper( + logs.get_summary, + ) diff --git a/src/cas_parser/resources/verify_token.py b/src/cas_parser/resources/verify_token.py new file mode 100644 index 0000000..06981d4 --- /dev/null +++ b/src/cas_parser/resources/verify_token.py @@ -0,0 +1,143 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from .._types import Body, Query, Headers, NotGiven, not_given +from .._compat import cached_property +from .._resource import SyncAPIResource, AsyncAPIResource +from .._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from .._base_client import make_request_options +from ..types.verify_token_verify_response import VerifyTokenVerifyResponse + +__all__ = ["VerifyTokenResource", "AsyncVerifyTokenResource"] + + +class VerifyTokenResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> VerifyTokenResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/CASParser/cas-parser-python#accessing-raw-response-data-eg-headers + """ + return VerifyTokenResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> VerifyTokenResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/CASParser/cas-parser-python#with_streaming_response + """ + return VerifyTokenResourceWithStreamingResponse(self) + + def verify( + self, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VerifyTokenVerifyResponse: + """Verify an access token and check if it's still valid. + + Useful for debugging token + issues. + """ + return self._post( + "/v1/token/verify", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=VerifyTokenVerifyResponse, + ) + + +class AsyncVerifyTokenResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncVerifyTokenResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/CASParser/cas-parser-python#accessing-raw-response-data-eg-headers + """ + return AsyncVerifyTokenResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncVerifyTokenResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/CASParser/cas-parser-python#with_streaming_response + """ + return AsyncVerifyTokenResourceWithStreamingResponse(self) + + async def verify( + self, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VerifyTokenVerifyResponse: + """Verify an access token and check if it's still valid. + + Useful for debugging token + issues. + """ + return await self._post( + "/v1/token/verify", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=VerifyTokenVerifyResponse, + ) + + +class VerifyTokenResourceWithRawResponse: + def __init__(self, verify_token: VerifyTokenResource) -> None: + self._verify_token = verify_token + + self.verify = to_raw_response_wrapper( + verify_token.verify, + ) + + +class AsyncVerifyTokenResourceWithRawResponse: + def __init__(self, verify_token: AsyncVerifyTokenResource) -> None: + self._verify_token = verify_token + + self.verify = async_to_raw_response_wrapper( + verify_token.verify, + ) + + +class VerifyTokenResourceWithStreamingResponse: + def __init__(self, verify_token: VerifyTokenResource) -> None: + self._verify_token = verify_token + + self.verify = to_streamed_response_wrapper( + verify_token.verify, + ) + + +class AsyncVerifyTokenResourceWithStreamingResponse: + def __init__(self, verify_token: AsyncVerifyTokenResource) -> None: + self._verify_token = verify_token + + self.verify = async_to_streamed_response_wrapper( + verify_token.verify, + ) diff --git a/src/cas_parser/types/__init__.py b/src/cas_parser/types/__init__.py index ee5666d..269b048 100644 --- a/src/cas_parser/types/__init__.py +++ b/src/cas_parser/types/__init__.py @@ -5,18 +5,32 @@ from .transaction import Transaction as Transaction from .linked_holder import LinkedHolder as LinkedHolder from .unified_response import UnifiedResponse as UnifiedResponse +from .log_create_params import LogCreateParams as LogCreateParams from .nsdl_parse_params import NsdlParseParams as NsdlParseParams +from .log_create_response import LogCreateResponse as LogCreateResponse from .cdsl_parse_pdf_params import CdslParsePdfParams as CdslParsePdfParams +from .credit_check_response import CreditCheckResponse as CreditCheckResponse +from .log_get_summary_params import LogGetSummaryParams as LogGetSummaryParams +from .log_get_summary_response import LogGetSummaryResponse as LogGetSummaryResponse +from .inbound_email_list_params import InboundEmailListParams as InboundEmailListParams +from .access_token_create_params import AccessTokenCreateParams as AccessTokenCreateParams from .cams_kfintech_parse_params import CamsKfintechParseParams as CamsKfintechParseParams from .contract_note_parse_params import ContractNoteParseParams as ContractNoteParseParams from .inbox_connect_email_params import InboxConnectEmailParams as InboxConnectEmailParams from .smart_parse_cas_pdf_params import SmartParseCasPdfParams as SmartParseCasPdfParams +from .inbound_email_create_params import InboundEmailCreateParams as InboundEmailCreateParams +from .inbound_email_list_response import InboundEmailListResponse as InboundEmailListResponse from .inbox_list_cas_files_params import InboxListCasFilesParams as InboxListCasFilesParams +from .access_token_create_response import AccessTokenCreateResponse as AccessTokenCreateResponse from .contract_note_parse_response import ContractNoteParseResponse as ContractNoteParseResponse from .inbox_connect_email_response import InboxConnectEmailResponse as InboxConnectEmailResponse from .kfintech_generate_cas_params import KfintechGenerateCasParams as KfintechGenerateCasParams +from .verify_token_verify_response import VerifyTokenVerifyResponse as VerifyTokenVerifyResponse +from .inbound_email_create_response import InboundEmailCreateResponse as InboundEmailCreateResponse +from .inbound_email_delete_response import InboundEmailDeleteResponse as InboundEmailDeleteResponse from .inbox_list_cas_files_response import InboxListCasFilesResponse as InboxListCasFilesResponse from .kfintech_generate_cas_response import KfintechGenerateCasResponse as KfintechGenerateCasResponse +from .inbound_email_retrieve_response import InboundEmailRetrieveResponse as InboundEmailRetrieveResponse from .inbox_disconnect_email_response import InboxDisconnectEmailResponse as InboxDisconnectEmailResponse from .inbox_check_connection_status_response import ( InboxCheckConnectionStatusResponse as InboxCheckConnectionStatusResponse, diff --git a/src/cas_parser/types/access_token_create_params.py b/src/cas_parser/types/access_token_create_params.py new file mode 100644 index 0000000..1d3f392 --- /dev/null +++ b/src/cas_parser/types/access_token_create_params.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import TypedDict + +__all__ = ["AccessTokenCreateParams"] + + +class AccessTokenCreateParams(TypedDict, total=False): + expiry_minutes: int + """Token validity in minutes (max 60)""" diff --git a/src/cas_parser/types/access_token_create_response.py b/src/cas_parser/types/access_token_create_response.py new file mode 100644 index 0000000..9a03c8c --- /dev/null +++ b/src/cas_parser/types/access_token_create_response.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from .._models import BaseModel + +__all__ = ["AccessTokenCreateResponse"] + + +class AccessTokenCreateResponse(BaseModel): + access_token: Optional[str] = None + """The at\\__ prefixed access token""" + + expires_in: Optional[int] = None + """Token validity in seconds""" + + token_type: Optional[str] = None + """Always "api_key" - token is a drop-in replacement for x-api-key header""" diff --git a/src/cas_parser/types/credit_check_response.py b/src/cas_parser/types/credit_check_response.py new file mode 100644 index 0000000..9396b9f --- /dev/null +++ b/src/cas_parser/types/credit_check_response.py @@ -0,0 +1,28 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime + +from .._models import BaseModel + +__all__ = ["CreditCheckResponse"] + + +class CreditCheckResponse(BaseModel): + enabled_features: Optional[List[str]] = None + """List of API features enabled for your plan""" + + is_unlimited: Optional[bool] = None + """Whether the account has unlimited credits""" + + limit: Optional[int] = None + """Total credit limit for billing period""" + + remaining: Optional[float] = None + """Remaining credits (null if unlimited)""" + + resets_at: Optional[datetime] = None + """When credits reset (ISO 8601)""" + + used: Optional[float] = None + """Number of credits used this billing period""" diff --git a/src/cas_parser/types/inbound_email_create_params.py b/src/cas_parser/types/inbound_email_create_params.py new file mode 100644 index 0000000..356d7e1 --- /dev/null +++ b/src/cas_parser/types/inbound_email_create_params.py @@ -0,0 +1,47 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, List +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["InboundEmailCreateParams"] + + +class InboundEmailCreateParams(TypedDict, total=False): + callback_url: Required[str] + """ + Webhook URL where we POST email notifications. Must be HTTPS in production (HTTP + allowed for localhost during development). + """ + + alias: str + """Optional custom email prefix for user-friendly addresses. + + - Must be 3-32 characters + - Alphanumeric + hyphens only + - Must start and end with letter/number + - Example: `john-portfolio@import.casparser.in` + - If omitted, generates random ID like `ie_abc123xyz@import.casparser.in` + """ + + allowed_sources: List[Literal["cdsl", "nsdl", "cams", "kfintech"]] + """Filter emails by CAS provider. If omitted, accepts all providers. + + - `cdsl` → eCAS@cdslstatement.com + - `nsdl` → NSDL-CAS@nsdl.co.in + - `cams` → donotreply@camsonline.com + - `kfintech` → samfS@kfintech.com + """ + + metadata: Dict[str, str] + """ + Optional key-value pairs (max 10) to include in webhook payload. Useful for + passing context like plan_type, campaign_id, etc. + """ + + reference: str + """ + Your internal identifier (e.g., user_id, account_id). Returned in webhook + payload for correlation. + """ diff --git a/src/cas_parser/types/inbound_email_create_response.py b/src/cas_parser/types/inbound_email_create_response.py new file mode 100644 index 0000000..29f89dc --- /dev/null +++ b/src/cas_parser/types/inbound_email_create_response.py @@ -0,0 +1,40 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, List, Optional +from datetime import datetime +from typing_extensions import Literal + +from .._models import BaseModel + +__all__ = ["InboundEmailCreateResponse"] + + +class InboundEmailCreateResponse(BaseModel): + """An inbound email address for receiving forwarded CAS emails""" + + allowed_sources: Optional[List[Literal["cdsl", "nsdl", "cams", "kfintech"]]] = None + """Accepted CAS providers (empty = all)""" + + callback_url: Optional[str] = None + """Webhook URL for email notifications""" + + created_at: Optional[datetime] = None + """When the mailbox was created""" + + email: Optional[str] = None + """The inbound email address to forward CAS statements to""" + + inbound_email_id: Optional[str] = None + """Unique inbound email identifier""" + + metadata: Optional[Dict[str, str]] = None + """Custom key-value metadata""" + + reference: Optional[str] = None + """Your internal reference identifier""" + + status: Optional[Literal["active", "paused"]] = None + """Current mailbox status""" + + updated_at: Optional[datetime] = None + """When the mailbox was last updated""" diff --git a/src/cas_parser/types/inbound_email_delete_response.py b/src/cas_parser/types/inbound_email_delete_response.py new file mode 100644 index 0000000..fdb55b2 --- /dev/null +++ b/src/cas_parser/types/inbound_email_delete_response.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from .._models import BaseModel + +__all__ = ["InboundEmailDeleteResponse"] + + +class InboundEmailDeleteResponse(BaseModel): + msg: Optional[str] = None + + status: Optional[str] = None diff --git a/src/cas_parser/types/inbound_email_list_params.py b/src/cas_parser/types/inbound_email_list_params.py new file mode 100644 index 0000000..c70d034 --- /dev/null +++ b/src/cas_parser/types/inbound_email_list_params.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["InboundEmailListParams"] + + +class InboundEmailListParams(TypedDict, total=False): + limit: int + """Maximum number of inbound emails to return""" + + offset: int + """Pagination offset""" + + status: Literal["active", "paused", "all"] + """Filter by status""" diff --git a/src/cas_parser/types/inbound_email_list_response.py b/src/cas_parser/types/inbound_email_list_response.py new file mode 100644 index 0000000..b1eea1b --- /dev/null +++ b/src/cas_parser/types/inbound_email_list_response.py @@ -0,0 +1,53 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, List, Optional +from datetime import datetime +from typing_extensions import Literal + +from .._models import BaseModel + +__all__ = ["InboundEmailListResponse", "InboundEmail"] + + +class InboundEmail(BaseModel): + """An inbound email address for receiving forwarded CAS emails""" + + allowed_sources: Optional[List[Literal["cdsl", "nsdl", "cams", "kfintech"]]] = None + """Accepted CAS providers (empty = all)""" + + callback_url: Optional[str] = None + """Webhook URL for email notifications""" + + created_at: Optional[datetime] = None + """When the mailbox was created""" + + email: Optional[str] = None + """The inbound email address to forward CAS statements to""" + + inbound_email_id: Optional[str] = None + """Unique inbound email identifier""" + + metadata: Optional[Dict[str, str]] = None + """Custom key-value metadata""" + + reference: Optional[str] = None + """Your internal reference identifier""" + + status: Optional[Literal["active", "paused"]] = None + """Current mailbox status""" + + updated_at: Optional[datetime] = None + """When the mailbox was last updated""" + + +class InboundEmailListResponse(BaseModel): + inbound_emails: Optional[List[InboundEmail]] = None + + limit: Optional[int] = None + + offset: Optional[int] = None + + status: Optional[str] = None + + total: Optional[int] = None + """Total number of inbound emails (for pagination)""" diff --git a/src/cas_parser/types/inbound_email_retrieve_response.py b/src/cas_parser/types/inbound_email_retrieve_response.py new file mode 100644 index 0000000..601fc87 --- /dev/null +++ b/src/cas_parser/types/inbound_email_retrieve_response.py @@ -0,0 +1,40 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, List, Optional +from datetime import datetime +from typing_extensions import Literal + +from .._models import BaseModel + +__all__ = ["InboundEmailRetrieveResponse"] + + +class InboundEmailRetrieveResponse(BaseModel): + """An inbound email address for receiving forwarded CAS emails""" + + allowed_sources: Optional[List[Literal["cdsl", "nsdl", "cams", "kfintech"]]] = None + """Accepted CAS providers (empty = all)""" + + callback_url: Optional[str] = None + """Webhook URL for email notifications""" + + created_at: Optional[datetime] = None + """When the mailbox was created""" + + email: Optional[str] = None + """The inbound email address to forward CAS statements to""" + + inbound_email_id: Optional[str] = None + """Unique inbound email identifier""" + + metadata: Optional[Dict[str, str]] = None + """Custom key-value metadata""" + + reference: Optional[str] = None + """Your internal reference identifier""" + + status: Optional[Literal["active", "paused"]] = None + """Current mailbox status""" + + updated_at: Optional[datetime] = None + """When the mailbox was last updated""" diff --git a/src/cas_parser/types/log_create_params.py b/src/cas_parser/types/log_create_params.py new file mode 100644 index 0000000..6104297 --- /dev/null +++ b/src/cas_parser/types/log_create_params.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from datetime import datetime +from typing_extensions import Annotated, TypedDict + +from .._utils import PropertyInfo + +__all__ = ["LogCreateParams"] + + +class LogCreateParams(TypedDict, total=False): + end_time: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """End time filter (ISO 8601). Defaults to now.""" + + limit: int + """Maximum number of logs to return""" + + start_time: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """Start time filter (ISO 8601). Defaults to 30 days ago.""" diff --git a/src/cas_parser/types/log_create_response.py b/src/cas_parser/types/log_create_response.py new file mode 100644 index 0000000..446d6e5 --- /dev/null +++ b/src/cas_parser/types/log_create_response.py @@ -0,0 +1,37 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime + +from .._models import BaseModel + +__all__ = ["LogCreateResponse", "Log"] + + +class Log(BaseModel): + credits: Optional[float] = None + """Credits consumed for this request""" + + feature: Optional[str] = None + """API feature used""" + + path: Optional[str] = None + """API endpoint path""" + + request_id: Optional[str] = None + """Unique request identifier""" + + status_code: Optional[int] = None + """HTTP response status code""" + + timestamp: Optional[datetime] = None + """When the request was made""" + + +class LogCreateResponse(BaseModel): + count: Optional[int] = None + """Number of logs returned""" + + logs: Optional[List[Log]] = None + + status: Optional[str] = None diff --git a/src/cas_parser/types/log_get_summary_params.py b/src/cas_parser/types/log_get_summary_params.py new file mode 100644 index 0000000..fc9ffe7 --- /dev/null +++ b/src/cas_parser/types/log_get_summary_params.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from datetime import datetime +from typing_extensions import Annotated, TypedDict + +from .._utils import PropertyInfo + +__all__ = ["LogGetSummaryParams"] + + +class LogGetSummaryParams(TypedDict, total=False): + end_time: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """End time filter (ISO 8601). Defaults to now.""" + + start_time: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """Start time filter (ISO 8601). Defaults to start of current month.""" diff --git a/src/cas_parser/types/log_get_summary_response.py b/src/cas_parser/types/log_get_summary_response.py new file mode 100644 index 0000000..d947f84 --- /dev/null +++ b/src/cas_parser/types/log_get_summary_response.py @@ -0,0 +1,35 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from .._models import BaseModel + +__all__ = ["LogGetSummaryResponse", "Summary", "SummaryByFeature"] + + +class SummaryByFeature(BaseModel): + credits: Optional[float] = None + """Credits consumed by this feature""" + + feature: Optional[str] = None + """API feature name""" + + requests: Optional[int] = None + """Number of requests for this feature""" + + +class Summary(BaseModel): + by_feature: Optional[List[SummaryByFeature]] = None + """Usage breakdown by feature""" + + total_credits: Optional[float] = None + """Total credits consumed in the period""" + + total_requests: Optional[int] = None + """Total API requests made in the period""" + + +class LogGetSummaryResponse(BaseModel): + status: Optional[str] = None + + summary: Optional[Summary] = None diff --git a/src/cas_parser/types/verify_token_verify_response.py b/src/cas_parser/types/verify_token_verify_response.py new file mode 100644 index 0000000..fcfebe7 --- /dev/null +++ b/src/cas_parser/types/verify_token_verify_response.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from .._models import BaseModel + +__all__ = ["VerifyTokenVerifyResponse"] + + +class VerifyTokenVerifyResponse(BaseModel): + error: Optional[str] = None + """Error message (only shown if invalid)""" + + masked_api_key: Optional[str] = None + """Masked API key (only shown if valid)""" + + valid: Optional[bool] = None + """Whether the token is valid""" diff --git a/tests/api_resources/test_access_token.py b/tests/api_resources/test_access_token.py new file mode 100644 index 0000000..32d63c9 --- /dev/null +++ b/tests/api_resources/test_access_token.py @@ -0,0 +1,96 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cas_parser import CasParser, AsyncCasParser +from tests.utils import assert_matches_type +from cas_parser.types import AccessTokenCreateResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestAccessToken: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create(self, client: CasParser) -> None: + access_token = client.access_token.create() + assert_matches_type(AccessTokenCreateResponse, access_token, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create_with_all_params(self, client: CasParser) -> None: + access_token = client.access_token.create( + expiry_minutes=60, + ) + assert_matches_type(AccessTokenCreateResponse, access_token, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_create(self, client: CasParser) -> None: + response = client.access_token.with_raw_response.create() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + access_token = response.parse() + assert_matches_type(AccessTokenCreateResponse, access_token, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_create(self, client: CasParser) -> None: + with client.access_token.with_streaming_response.create() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + access_token = response.parse() + assert_matches_type(AccessTokenCreateResponse, access_token, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncAccessToken: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create(self, async_client: AsyncCasParser) -> None: + access_token = await async_client.access_token.create() + assert_matches_type(AccessTokenCreateResponse, access_token, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCasParser) -> None: + access_token = await async_client.access_token.create( + expiry_minutes=60, + ) + assert_matches_type(AccessTokenCreateResponse, access_token, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_create(self, async_client: AsyncCasParser) -> None: + response = await async_client.access_token.with_raw_response.create() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + access_token = await response.parse() + assert_matches_type(AccessTokenCreateResponse, access_token, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCasParser) -> None: + async with async_client.access_token.with_streaming_response.create() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + access_token = await response.parse() + assert_matches_type(AccessTokenCreateResponse, access_token, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_credits.py b/tests/api_resources/test_credits.py new file mode 100644 index 0000000..8538889 --- /dev/null +++ b/tests/api_resources/test_credits.py @@ -0,0 +1,80 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cas_parser import CasParser, AsyncCasParser +from tests.utils import assert_matches_type +from cas_parser.types import CreditCheckResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestCredits: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_check(self, client: CasParser) -> None: + credit = client.credits.check() + assert_matches_type(CreditCheckResponse, credit, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_check(self, client: CasParser) -> None: + response = client.credits.with_raw_response.check() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + credit = response.parse() + assert_matches_type(CreditCheckResponse, credit, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_check(self, client: CasParser) -> None: + with client.credits.with_streaming_response.check() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + credit = response.parse() + assert_matches_type(CreditCheckResponse, credit, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncCredits: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_check(self, async_client: AsyncCasParser) -> None: + credit = await async_client.credits.check() + assert_matches_type(CreditCheckResponse, credit, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_check(self, async_client: AsyncCasParser) -> None: + response = await async_client.credits.with_raw_response.check() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + credit = await response.parse() + assert_matches_type(CreditCheckResponse, credit, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_check(self, async_client: AsyncCasParser) -> None: + async with async_client.credits.with_streaming_response.check() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + credit = await response.parse() + assert_matches_type(CreditCheckResponse, credit, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_inbound_email.py b/tests/api_resources/test_inbound_email.py new file mode 100644 index 0000000..6970229 --- /dev/null +++ b/tests/api_resources/test_inbound_email.py @@ -0,0 +1,371 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cas_parser import CasParser, AsyncCasParser +from tests.utils import assert_matches_type +from cas_parser.types import ( + InboundEmailListResponse, + InboundEmailCreateResponse, + InboundEmailDeleteResponse, + InboundEmailRetrieveResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestInboundEmail: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create(self, client: CasParser) -> None: + inbound_email = client.inbound_email.create( + callback_url="https://api.yourapp.com/webhooks/cas-email", + ) + assert_matches_type(InboundEmailCreateResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create_with_all_params(self, client: CasParser) -> None: + inbound_email = client.inbound_email.create( + callback_url="https://api.yourapp.com/webhooks/cas-email", + alias="john-portfolio", + allowed_sources=["cdsl", "nsdl"], + metadata={ + "plan": "premium", + "source": "onboarding", + }, + reference="user_12345", + ) + assert_matches_type(InboundEmailCreateResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_create(self, client: CasParser) -> None: + response = client.inbound_email.with_raw_response.create( + callback_url="https://api.yourapp.com/webhooks/cas-email", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + inbound_email = response.parse() + assert_matches_type(InboundEmailCreateResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_create(self, client: CasParser) -> None: + with client.inbound_email.with_streaming_response.create( + callback_url="https://api.yourapp.com/webhooks/cas-email", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + inbound_email = response.parse() + assert_matches_type(InboundEmailCreateResponse, inbound_email, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_retrieve(self, client: CasParser) -> None: + inbound_email = client.inbound_email.retrieve( + "ie_a1b2c3d4e5f6", + ) + assert_matches_type(InboundEmailRetrieveResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_retrieve(self, client: CasParser) -> None: + response = client.inbound_email.with_raw_response.retrieve( + "ie_a1b2c3d4e5f6", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + inbound_email = response.parse() + assert_matches_type(InboundEmailRetrieveResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_retrieve(self, client: CasParser) -> None: + with client.inbound_email.with_streaming_response.retrieve( + "ie_a1b2c3d4e5f6", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + inbound_email = response.parse() + assert_matches_type(InboundEmailRetrieveResponse, inbound_email, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_retrieve(self, client: CasParser) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbound_email_id` but received ''"): + client.inbound_email.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: CasParser) -> None: + inbound_email = client.inbound_email.list() + assert_matches_type(InboundEmailListResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_with_all_params(self, client: CasParser) -> None: + inbound_email = client.inbound_email.list( + limit=1, + offset=0, + status="active", + ) + assert_matches_type(InboundEmailListResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: CasParser) -> None: + response = client.inbound_email.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + inbound_email = response.parse() + assert_matches_type(InboundEmailListResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: CasParser) -> None: + with client.inbound_email.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + inbound_email = response.parse() + assert_matches_type(InboundEmailListResponse, inbound_email, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_delete(self, client: CasParser) -> None: + inbound_email = client.inbound_email.delete( + "inbound_email_id", + ) + assert_matches_type(InboundEmailDeleteResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_delete(self, client: CasParser) -> None: + response = client.inbound_email.with_raw_response.delete( + "inbound_email_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + inbound_email = response.parse() + assert_matches_type(InboundEmailDeleteResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_delete(self, client: CasParser) -> None: + with client.inbound_email.with_streaming_response.delete( + "inbound_email_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + inbound_email = response.parse() + assert_matches_type(InboundEmailDeleteResponse, inbound_email, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_delete(self, client: CasParser) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbound_email_id` but received ''"): + client.inbound_email.with_raw_response.delete( + "", + ) + + +class TestAsyncInboundEmail: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create(self, async_client: AsyncCasParser) -> None: + inbound_email = await async_client.inbound_email.create( + callback_url="https://api.yourapp.com/webhooks/cas-email", + ) + assert_matches_type(InboundEmailCreateResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCasParser) -> None: + inbound_email = await async_client.inbound_email.create( + callback_url="https://api.yourapp.com/webhooks/cas-email", + alias="john-portfolio", + allowed_sources=["cdsl", "nsdl"], + metadata={ + "plan": "premium", + "source": "onboarding", + }, + reference="user_12345", + ) + assert_matches_type(InboundEmailCreateResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_create(self, async_client: AsyncCasParser) -> None: + response = await async_client.inbound_email.with_raw_response.create( + callback_url="https://api.yourapp.com/webhooks/cas-email", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + inbound_email = await response.parse() + assert_matches_type(InboundEmailCreateResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCasParser) -> None: + async with async_client.inbound_email.with_streaming_response.create( + callback_url="https://api.yourapp.com/webhooks/cas-email", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + inbound_email = await response.parse() + assert_matches_type(InboundEmailCreateResponse, inbound_email, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_retrieve(self, async_client: AsyncCasParser) -> None: + inbound_email = await async_client.inbound_email.retrieve( + "ie_a1b2c3d4e5f6", + ) + assert_matches_type(InboundEmailRetrieveResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncCasParser) -> None: + response = await async_client.inbound_email.with_raw_response.retrieve( + "ie_a1b2c3d4e5f6", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + inbound_email = await response.parse() + assert_matches_type(InboundEmailRetrieveResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncCasParser) -> None: + async with async_client.inbound_email.with_streaming_response.retrieve( + "ie_a1b2c3d4e5f6", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + inbound_email = await response.parse() + assert_matches_type(InboundEmailRetrieveResponse, inbound_email, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncCasParser) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbound_email_id` but received ''"): + await async_client.inbound_email.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncCasParser) -> None: + inbound_email = await async_client.inbound_email.list() + assert_matches_type(InboundEmailListResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCasParser) -> None: + inbound_email = await async_client.inbound_email.list( + limit=1, + offset=0, + status="active", + ) + assert_matches_type(InboundEmailListResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncCasParser) -> None: + response = await async_client.inbound_email.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + inbound_email = await response.parse() + assert_matches_type(InboundEmailListResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCasParser) -> None: + async with async_client.inbound_email.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + inbound_email = await response.parse() + assert_matches_type(InboundEmailListResponse, inbound_email, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete(self, async_client: AsyncCasParser) -> None: + inbound_email = await async_client.inbound_email.delete( + "inbound_email_id", + ) + assert_matches_type(InboundEmailDeleteResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCasParser) -> None: + response = await async_client.inbound_email.with_raw_response.delete( + "inbound_email_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + inbound_email = await response.parse() + assert_matches_type(InboundEmailDeleteResponse, inbound_email, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCasParser) -> None: + async with async_client.inbound_email.with_streaming_response.delete( + "inbound_email_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + inbound_email = await response.parse() + assert_matches_type(InboundEmailDeleteResponse, inbound_email, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_delete(self, async_client: AsyncCasParser) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `inbound_email_id` but received ''"): + await async_client.inbound_email.with_raw_response.delete( + "", + ) diff --git a/tests/api_resources/test_logs.py b/tests/api_resources/test_logs.py new file mode 100644 index 0000000..43908ef --- /dev/null +++ b/tests/api_resources/test_logs.py @@ -0,0 +1,175 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cas_parser import CasParser, AsyncCasParser +from tests.utils import assert_matches_type +from cas_parser.types import LogCreateResponse, LogGetSummaryResponse +from cas_parser._utils import parse_datetime + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestLogs: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create(self, client: CasParser) -> None: + log = client.logs.create() + assert_matches_type(LogCreateResponse, log, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create_with_all_params(self, client: CasParser) -> None: + log = client.logs.create( + end_time=parse_datetime("2026-01-31T23:59:59Z"), + limit=1, + start_time=parse_datetime("2026-01-01T00:00:00Z"), + ) + assert_matches_type(LogCreateResponse, log, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_create(self, client: CasParser) -> None: + response = client.logs.with_raw_response.create() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + log = response.parse() + assert_matches_type(LogCreateResponse, log, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_create(self, client: CasParser) -> None: + with client.logs.with_streaming_response.create() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + log = response.parse() + assert_matches_type(LogCreateResponse, log, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_summary(self, client: CasParser) -> None: + log = client.logs.get_summary() + assert_matches_type(LogGetSummaryResponse, log, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_summary_with_all_params(self, client: CasParser) -> None: + log = client.logs.get_summary( + end_time=parse_datetime("2019-12-27T18:11:19.117Z"), + start_time=parse_datetime("2019-12-27T18:11:19.117Z"), + ) + assert_matches_type(LogGetSummaryResponse, log, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_get_summary(self, client: CasParser) -> None: + response = client.logs.with_raw_response.get_summary() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + log = response.parse() + assert_matches_type(LogGetSummaryResponse, log, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_get_summary(self, client: CasParser) -> None: + with client.logs.with_streaming_response.get_summary() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + log = response.parse() + assert_matches_type(LogGetSummaryResponse, log, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncLogs: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create(self, async_client: AsyncCasParser) -> None: + log = await async_client.logs.create() + assert_matches_type(LogCreateResponse, log, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCasParser) -> None: + log = await async_client.logs.create( + end_time=parse_datetime("2026-01-31T23:59:59Z"), + limit=1, + start_time=parse_datetime("2026-01-01T00:00:00Z"), + ) + assert_matches_type(LogCreateResponse, log, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_create(self, async_client: AsyncCasParser) -> None: + response = await async_client.logs.with_raw_response.create() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + log = await response.parse() + assert_matches_type(LogCreateResponse, log, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCasParser) -> None: + async with async_client.logs.with_streaming_response.create() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + log = await response.parse() + assert_matches_type(LogCreateResponse, log, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_summary(self, async_client: AsyncCasParser) -> None: + log = await async_client.logs.get_summary() + assert_matches_type(LogGetSummaryResponse, log, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_summary_with_all_params(self, async_client: AsyncCasParser) -> None: + log = await async_client.logs.get_summary( + end_time=parse_datetime("2019-12-27T18:11:19.117Z"), + start_time=parse_datetime("2019-12-27T18:11:19.117Z"), + ) + assert_matches_type(LogGetSummaryResponse, log, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_get_summary(self, async_client: AsyncCasParser) -> None: + response = await async_client.logs.with_raw_response.get_summary() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + log = await response.parse() + assert_matches_type(LogGetSummaryResponse, log, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_get_summary(self, async_client: AsyncCasParser) -> None: + async with async_client.logs.with_streaming_response.get_summary() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + log = await response.parse() + assert_matches_type(LogGetSummaryResponse, log, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_verify_token.py b/tests/api_resources/test_verify_token.py new file mode 100644 index 0000000..43e594d --- /dev/null +++ b/tests/api_resources/test_verify_token.py @@ -0,0 +1,80 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cas_parser import CasParser, AsyncCasParser +from tests.utils import assert_matches_type +from cas_parser.types import VerifyTokenVerifyResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestVerifyToken: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_verify(self, client: CasParser) -> None: + verify_token = client.verify_token.verify() + assert_matches_type(VerifyTokenVerifyResponse, verify_token, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_verify(self, client: CasParser) -> None: + response = client.verify_token.with_raw_response.verify() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + verify_token = response.parse() + assert_matches_type(VerifyTokenVerifyResponse, verify_token, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_verify(self, client: CasParser) -> None: + with client.verify_token.with_streaming_response.verify() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + verify_token = response.parse() + assert_matches_type(VerifyTokenVerifyResponse, verify_token, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncVerifyToken: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_verify(self, async_client: AsyncCasParser) -> None: + verify_token = await async_client.verify_token.verify() + assert_matches_type(VerifyTokenVerifyResponse, verify_token, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_verify(self, async_client: AsyncCasParser) -> None: + response = await async_client.verify_token.with_raw_response.verify() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + verify_token = await response.parse() + assert_matches_type(VerifyTokenVerifyResponse, verify_token, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_verify(self, async_client: AsyncCasParser) -> None: + async with async_client.verify_token.with_streaming_response.verify() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + verify_token = await response.parse() + assert_matches_type(VerifyTokenVerifyResponse, verify_token, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/test_client.py b/tests/test_client.py index ed6cfac..5a768aa 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -863,20 +863,20 @@ def test_parse_retry_after_header( @mock.patch("cas_parser._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, client: CasParser) -> None: - respx_mock.post("/v4/cams_kfintech/parse").mock(side_effect=httpx.TimeoutException("Test timeout error")) + respx_mock.post("/v1/credits").mock(side_effect=httpx.TimeoutException("Test timeout error")) with pytest.raises(APITimeoutError): - client.cams_kfintech.with_streaming_response.parse().__enter__() + client.credits.with_streaming_response.check().__enter__() assert _get_open_connections(client) == 0 @mock.patch("cas_parser._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client: CasParser) -> None: - respx_mock.post("/v4/cams_kfintech/parse").mock(return_value=httpx.Response(500)) + respx_mock.post("/v1/credits").mock(return_value=httpx.Response(500)) with pytest.raises(APIStatusError): - client.cams_kfintech.with_streaming_response.parse().__enter__() + client.credits.with_streaming_response.check().__enter__() assert _get_open_connections(client) == 0 @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @@ -903,9 +903,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: return httpx.Response(500) return httpx.Response(200) - respx_mock.post("/v4/cams_kfintech/parse").mock(side_effect=retry_handler) + respx_mock.post("/v1/credits").mock(side_effect=retry_handler) - response = client.cams_kfintech.with_raw_response.parse() + response = client.credits.with_raw_response.check() assert response.retries_taken == failures_before_success assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success @@ -927,9 +927,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: return httpx.Response(500) return httpx.Response(200) - respx_mock.post("/v4/cams_kfintech/parse").mock(side_effect=retry_handler) + respx_mock.post("/v1/credits").mock(side_effect=retry_handler) - response = client.cams_kfintech.with_raw_response.parse(extra_headers={"x-stainless-retry-count": Omit()}) + response = client.credits.with_raw_response.check(extra_headers={"x-stainless-retry-count": Omit()}) assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0 @@ -950,9 +950,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: return httpx.Response(500) return httpx.Response(200) - respx_mock.post("/v4/cams_kfintech/parse").mock(side_effect=retry_handler) + respx_mock.post("/v1/credits").mock(side_effect=retry_handler) - response = client.cams_kfintech.with_raw_response.parse(extra_headers={"x-stainless-retry-count": "42"}) + response = client.credits.with_raw_response.check(extra_headers={"x-stainless-retry-count": "42"}) assert response.http_request.headers.get("x-stainless-retry-count") == "42" @@ -1775,10 +1775,10 @@ async def test_parse_retry_after_header( async def test_retrying_timeout_errors_doesnt_leak( self, respx_mock: MockRouter, async_client: AsyncCasParser ) -> None: - respx_mock.post("/v4/cams_kfintech/parse").mock(side_effect=httpx.TimeoutException("Test timeout error")) + respx_mock.post("/v1/credits").mock(side_effect=httpx.TimeoutException("Test timeout error")) with pytest.raises(APITimeoutError): - await async_client.cams_kfintech.with_streaming_response.parse().__aenter__() + await async_client.credits.with_streaming_response.check().__aenter__() assert _get_open_connections(async_client) == 0 @@ -1787,10 +1787,10 @@ async def test_retrying_timeout_errors_doesnt_leak( async def test_retrying_status_errors_doesnt_leak( self, respx_mock: MockRouter, async_client: AsyncCasParser ) -> None: - respx_mock.post("/v4/cams_kfintech/parse").mock(return_value=httpx.Response(500)) + respx_mock.post("/v1/credits").mock(return_value=httpx.Response(500)) with pytest.raises(APIStatusError): - await async_client.cams_kfintech.with_streaming_response.parse().__aenter__() + await async_client.credits.with_streaming_response.check().__aenter__() assert _get_open_connections(async_client) == 0 @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @@ -1817,9 +1817,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: return httpx.Response(500) return httpx.Response(200) - respx_mock.post("/v4/cams_kfintech/parse").mock(side_effect=retry_handler) + respx_mock.post("/v1/credits").mock(side_effect=retry_handler) - response = await client.cams_kfintech.with_raw_response.parse() + response = await client.credits.with_raw_response.check() assert response.retries_taken == failures_before_success assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success @@ -1841,9 +1841,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: return httpx.Response(500) return httpx.Response(200) - respx_mock.post("/v4/cams_kfintech/parse").mock(side_effect=retry_handler) + respx_mock.post("/v1/credits").mock(side_effect=retry_handler) - response = await client.cams_kfintech.with_raw_response.parse(extra_headers={"x-stainless-retry-count": Omit()}) + response = await client.credits.with_raw_response.check(extra_headers={"x-stainless-retry-count": Omit()}) assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0 @@ -1864,9 +1864,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: return httpx.Response(500) return httpx.Response(200) - respx_mock.post("/v4/cams_kfintech/parse").mock(side_effect=retry_handler) + respx_mock.post("/v1/credits").mock(side_effect=retry_handler) - response = await client.cams_kfintech.with_raw_response.parse(extra_headers={"x-stainless-retry-count": "42"}) + response = await client.credits.with_raw_response.check(extra_headers={"x-stainless-retry-count": "42"}) assert response.http_request.headers.get("x-stainless-retry-count") == "42" From cc9f13cf61ce21e065c4b0b9700690bd5873011c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 03:00:49 +0000 Subject: [PATCH 5/6] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index cdf3c0a..49508b3 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-d9763d006969b49a1473851069fdfa429eb13133b64103a62963bb70ddb22305.yml openapi_spec_hash: 6aee689b7a759b12c85c088c15e29bc0 -config_hash: d54f39abb185904495bef7c5f8702746 +config_hash: 4ab3e1ee76a463e0ed214541260ee12e From ec44e79b3f4a20e22a1eeee297ab03a1605054f5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 03:01:03 +0000 Subject: [PATCH 6/6] release: 1.5.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 11 +++++++++++ pyproject.toml | 2 +- src/cas_parser/_version.py | 2 +- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 7325798..fbd9082 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.4.1" + ".": "1.5.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 61d9a73..1fe0243 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 1.5.0 (2026-02-23) + +Full Changelog: [v1.4.1...v1.5.0](https://github.com/CASParser/cas-parser-python/compare/v1.4.1...v1.5.0) + +### Features + +* **api:** api update ([8a5eeaa](https://github.com/CASParser/cas-parser-python/commit/8a5eeaa3334343c0a5e8268d06c0c25d7dfdef00)) +* **api:** api update ([478ce0c](https://github.com/CASParser/cas-parser-python/commit/478ce0c2535de083e5c6f9248d0df77e6bafb410)) +* **api:** api update ([dcf866c](https://github.com/CASParser/cas-parser-python/commit/dcf866c9577a219abb273e5b34e2c95bda3404f2)) +* **api:** manual updates ([a4d6336](https://github.com/CASParser/cas-parser-python/commit/a4d6336829387e982ac938935252129ff5131f65)) + ## 1.4.1 (2026-02-20) Full Changelog: [v1.4.0...v1.4.1](https://github.com/CASParser/cas-parser-python/compare/v1.4.0...v1.4.1) diff --git a/pyproject.toml b/pyproject.toml index e9c0aea..4e79dc8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cas-parser-python" -version = "1.4.1" +version = "1.5.0" description = "The official Python library for the cas-parser API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/cas_parser/_version.py b/src/cas_parser/_version.py index eaa6152..e73e451 100644 --- a/src/cas_parser/_version.py +++ b/src/cas_parser/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "cas_parser" -__version__ = "1.4.1" # x-release-please-version +__version__ = "1.5.0" # x-release-please-version