From 0b4196ba6d50828f80e0b10ee8fc7c0a692345e7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 30 Jul 2026 16:17:29 +0000 Subject: [PATCH 01/12] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index fa5ea03f..6629cefd 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 102 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-7f89d003ee5886a49dcba4317709b3631185a517c455e0dbf12130dadc1a73c3.yml -openapi_spec_hash: b6057ce27ebb04cdd19c0f006774ce65 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-731302277aee60aec3f8598b95909f59523993209a3f7c9a13cd59bfb2c5e14b.yml +openapi_spec_hash: 59fdcff99b1ae4c198c826713d7722bc config_hash: ff20af11692df5be71f1ef46d41ef365 From dd004d0da3837f4e789d5c7e53b3fe3a5145f441 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 30 Jul 2026 19:17:29 +0000 Subject: [PATCH 02/12] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 6629cefd..f5227672 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 102 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-731302277aee60aec3f8598b95909f59523993209a3f7c9a13cd59bfb2c5e14b.yml -openapi_spec_hash: 59fdcff99b1ae4c198c826713d7722bc +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-6275174f0a62e012c50643d471b3e82b98707979492dc1a405ef34fcf13f5b45.yml +openapi_spec_hash: b3bc03eeb0908def5bd1b702908061a9 config_hash: ff20af11692df5be71f1ef46d41ef365 From d26dd846a94df350e4d46d1f3da55d4ff1ee55b0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 00:17:23 +0000 Subject: [PATCH 03/12] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index f5227672..a30700eb 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 102 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-6275174f0a62e012c50643d471b3e82b98707979492dc1a405ef34fcf13f5b45.yml -openapi_spec_hash: b3bc03eeb0908def5bd1b702908061a9 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-3f5a04157e254375d835a818f51a81159912b74c61102f5657f0fa77cca705d3.yml +openapi_spec_hash: 11040dfe373082a77a735046ce51595a config_hash: ff20af11692df5be71f1ef46d41ef365 From 60b5acb731256848293bd7d291419f4a5f076d1d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 01:17:32 +0000 Subject: [PATCH 04/12] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index a30700eb..030dada9 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 102 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-3f5a04157e254375d835a818f51a81159912b74c61102f5657f0fa77cca705d3.yml -openapi_spec_hash: 11040dfe373082a77a735046ce51595a +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-a5a8e13afc85e5c19a60def730482b6f24db368291566bdd371d3bd042828977.yml +openapi_spec_hash: 96fc55acf2c00d26348969ab245ebb43 config_hash: ff20af11692df5be71f1ef46d41ef365 From bb03785f1af4db9afee5f7adb0f77d63a38a52ca Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 14:17:28 +0000 Subject: [PATCH 05/12] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 030dada9..92bfe1ea 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 102 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-a5a8e13afc85e5c19a60def730482b6f24db368291566bdd371d3bd042828977.yml -openapi_spec_hash: 96fc55acf2c00d26348969ab245ebb43 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-3d8d64b43abe76c2c8f97fb7808853406b98388277f8f0d2fedd19455c85d0ff.yml +openapi_spec_hash: ab67ef987b1c1c1545bd5471ff454c23 config_hash: ff20af11692df5be71f1ef46d41ef365 From 6c38bfbb3d9e564499611a33396c310d69e375e4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 17:17:28 +0000 Subject: [PATCH 06/12] feat(api): api update --- .stats.yml | 4 +-- .../types/prompt_answers_v2_response.py | 18 ++++++++++++- .../prompt_stream_answers_v2_response.py | 25 ++++++++++++++++++- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/.stats.yml b/.stats.yml index 92bfe1ea..a74b9e76 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 102 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-3d8d64b43abe76c2c8f97fb7808853406b98388277f8f0d2fedd19455c85d0ff.yml -openapi_spec_hash: ab67ef987b1c1c1545bd5471ff454c23 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-9c616fae4c662c1e1b3d372a69885770b65f9ad3e38db9646ca1cb1d616361b8.yml +openapi_spec_hash: c9aa22ae14a458426bc871331b3224d8 config_hash: ff20af11692df5be71f1ef46d41ef365 diff --git a/src/profound/types/prompt_answers_v2_response.py b/src/profound/types/prompt_answers_v2_response.py index 143aa83a..0b8bdda2 100644 --- a/src/profound/types/prompt_answers_v2_response.py +++ b/src/profound/types/prompt_answers_v2_response.py @@ -6,7 +6,13 @@ from .._models import BaseModel -__all__ = ["PromptAnswersV2Response", "Data", "DataCitationDetail", "DataModel", "Info"] +__all__ = ["PromptAnswersV2Response", "Data", "DataCitationDetail", "DataCitationDetailGroup", "DataModel", "Info"] + + +class DataCitationDetailGroup(BaseModel): + group_id: int + + group_position: int class DataCitationDetail(BaseModel): @@ -24,6 +30,10 @@ class DataCitationDetail(BaseModel): first_cited_at: Optional[str] = None + groups: Optional[List[DataCitationDetailGroup]] = None + + positions: Optional[List[int]] = None + text: Optional[str] = None @@ -44,6 +54,12 @@ class Data(BaseModel): analysis_types: Optional[List[str]] = None citation_details: Optional[List[DataCitationDetail]] = None + """Citation metadata. + + `positions` identify citation locations in the answer text. Each `groups` entry + represents a rendered citation pill; `group_position` is the source's position + within that pill. + """ citations: Optional[List[str]] = None diff --git a/src/profound/types/prompt_stream_answers_v2_response.py b/src/profound/types/prompt_stream_answers_v2_response.py index d3a30a6e..17565563 100644 --- a/src/profound/types/prompt_stream_answers_v2_response.py +++ b/src/profound/types/prompt_stream_answers_v2_response.py @@ -7,7 +7,14 @@ from .._models import BaseModel -__all__ = ["PromptStreamAnswersV2Response", "AnswersV2Info", "AnswerRow", "AnswerRowCitationDetail", "AnswerRowModel"] +__all__ = [ + "PromptStreamAnswersV2Response", + "AnswersV2Info", + "AnswerRow", + "AnswerRowCitationDetail", + "AnswerRowCitationDetailGroup", + "AnswerRowModel", +] class AnswersV2Info(BaseModel): @@ -50,6 +57,12 @@ def __getattr__(self, attr: str) -> object: ... __pydantic_extra__: Dict[str, object] +class AnswerRowCitationDetailGroup(BaseModel): + group_id: int + + group_position: int + + class AnswerRowCitationDetail(BaseModel): clean_url: str @@ -65,6 +78,10 @@ class AnswerRowCitationDetail(BaseModel): first_cited_at: Optional[str] = None + groups: Optional[List[AnswerRowCitationDetailGroup]] = None + + positions: Optional[List[int]] = None + text: Optional[str] = None @@ -82,6 +99,12 @@ class AnswerRow(BaseModel): analysis_types: Optional[List[str]] = None citation_details: Optional[List[AnswerRowCitationDetail]] = None + """Citation metadata. + + `positions` identify citation locations in the answer text. Each `groups` entry + represents a rendered citation pill; `group_position` is the source's position + within that pill. + """ citations: Optional[List[str]] = None From d81e9201bd0cc4492f518fc5be9378fa34ee994e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 18:17:33 +0000 Subject: [PATCH 07/12] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index a74b9e76..fe51989f 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 102 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-9c616fae4c662c1e1b3d372a69885770b65f9ad3e38db9646ca1cb1d616361b8.yml -openapi_spec_hash: c9aa22ae14a458426bc871331b3224d8 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-3d355fa7c4e1b8b96473d677823aa9238a27a44da33d8c88c4854f6f1ec000ab.yml +openapi_spec_hash: 2b0b9177a7ee8d32359b093d5ab98749 config_hash: ff20af11692df5be71f1ef46d41ef365 From 00b0e159f5b6e13db805dc88baf79dfe63d6667b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 19:17:31 +0000 Subject: [PATCH 08/12] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index fe51989f..21ec48ac 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 102 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-3d355fa7c4e1b8b96473d677823aa9238a27a44da33d8c88c4854f6f1ec000ab.yml -openapi_spec_hash: 2b0b9177a7ee8d32359b093d5ab98749 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-da7b9b99613eabe79b367623d552a6bc0f1aa18931a2c53f2543756ee9ae8d61.yml +openapi_spec_hash: 40e0fba93f23961dab07fb51124d563a config_hash: ff20af11692df5be71f1ef46d41ef365 From 0e3db087de1c038a5aca203722158857ed9aa395 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 21:17:35 +0000 Subject: [PATCH 09/12] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 21ec48ac..9260ad3a 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 102 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-da7b9b99613eabe79b367623d552a6bc0f1aa18931a2c53f2543756ee9ae8d61.yml -openapi_spec_hash: 40e0fba93f23961dab07fb51124d563a +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-bcaf63c0b7413453485a405e30a5d5b82f4cb29949cc0ba7e0af24fc5a49ea36.yml +openapi_spec_hash: 0f50b7862d9981f3837865b7e971bea7 config_hash: ff20af11692df5be71f1ef46d41ef365 From 29a4731fd6d06e3d85a0c5aac22589d406126c6e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 3 Aug 2026 15:13:53 +0000 Subject: [PATCH 10/12] feat(api): manual updates --- .stats.yml | 6 +- api.md | 28 ++ src/profound/_client.py | 87 ++++++- src/profound/resources/__init__.py | 28 ++ src/profound/resources/ads/__init__.py | 33 +++ src/profound/resources/ads/ads.py | 102 ++++++++ .../resources/ads/openai_ads/__init__.py | 33 +++ .../resources/ads/openai_ads/ad_account.py | 244 ++++++++++++++++++ .../resources/ads/openai_ads/openai_ads.py | 102 ++++++++ src/profound/resources/documents.py | 227 ++++++++++++++++ src/profound/types/__init__.py | 2 + src/profound/types/ads/__init__.py | 3 + src/profound/types/ads/openai_ads/__init__.py | 8 + .../ad_account_retrieve_insights_params.py | 38 +++ .../ad_account_retrieve_insights_response.py | 86 ++++++ src/profound/types/document_create_params.py | 34 +++ .../types/document_create_response.py | 34 +++ tests/api_resources/ads/__init__.py | 1 + .../api_resources/ads/openai_ads/__init__.py | 1 + .../ads/openai_ads/test_ad_account.py | 108 ++++++++ tests/api_resources/test_documents.py | 110 ++++++++ 21 files changed, 1311 insertions(+), 4 deletions(-) create mode 100644 src/profound/resources/ads/__init__.py create mode 100644 src/profound/resources/ads/ads.py create mode 100644 src/profound/resources/ads/openai_ads/__init__.py create mode 100644 src/profound/resources/ads/openai_ads/ad_account.py create mode 100644 src/profound/resources/ads/openai_ads/openai_ads.py create mode 100644 src/profound/resources/documents.py create mode 100644 src/profound/types/ads/__init__.py create mode 100644 src/profound/types/ads/openai_ads/__init__.py create mode 100644 src/profound/types/ads/openai_ads/ad_account_retrieve_insights_params.py create mode 100644 src/profound/types/ads/openai_ads/ad_account_retrieve_insights_response.py create mode 100644 src/profound/types/document_create_params.py create mode 100644 src/profound/types/document_create_response.py create mode 100644 tests/api_resources/ads/__init__.py create mode 100644 tests/api_resources/ads/openai_ads/__init__.py create mode 100644 tests/api_resources/ads/openai_ads/test_ad_account.py create mode 100644 tests/api_resources/test_documents.py diff --git a/.stats.yml b/.stats.yml index 9260ad3a..8c2e2d45 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 102 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-bcaf63c0b7413453485a405e30a5d5b82f4cb29949cc0ba7e0af24fc5a49ea36.yml +configured_endpoints: 104 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-dfea5ac8ff0b5b11ac1d8ad2079ecd3b70dc61860e7d084e98f362a578837d94.yml openapi_spec_hash: 0f50b7862d9981f3837865b7e971bea7 -config_hash: ff20af11692df5be71f1ef46d41ef365 +config_hash: 191a4ee80e1a76fd6ac596027c4ef244 diff --git a/api.md b/api.md index 6b557ba0..9e78dee1 100644 --- a/api.md +++ b/api.md @@ -449,3 +449,31 @@ from profound.types import IntegrationListResponse Methods: - client.integrations.list(\*\*params) -> IntegrationListResponse + +# Documents + +Types: + +```python +from profound.types import DocumentCreateResponse +``` + +Methods: + +- client.documents.create(\*\*params) -> DocumentCreateResponse + +# Ads + +## OpenAIAds + +### AdAccount + +Types: + +```python +from profound.types.ads.openai_ads import AdAccountRetrieveInsightsResponse +``` + +Methods: + +- client.ads.openai_ads.ad_account.retrieve_insights(\*\*params) -> AdAccountRetrieveInsightsResponse diff --git a/src/profound/_client.py b/src/profound/_client.py index e547da8f..f9d83750 100644 --- a/src/profound/_client.py +++ b/src/profound/_client.py @@ -36,8 +36,21 @@ ) if TYPE_CHECKING: - from .resources import agents, content, prompts, reports, projects, integrations, organizations, knowledge_bases + from .resources import ( + ads, + agents, + content, + prompts, + reports, + projects, + documents, + integrations, + organizations, + knowledge_bases, + ) + from .resources.ads.ads import AdsResource, AsyncAdsResource from .resources.prompts import PromptsResource, AsyncPromptsResource + from .resources.documents import DocumentsResource, AsyncDocumentsResource from .resources.integrations import IntegrationsResource, AsyncIntegrationsResource from .resources.agents.agents import AgentsResource, AsyncAgentsResource from .resources.content.content import ContentResource, AsyncContentResource @@ -204,6 +217,18 @@ def integrations(self) -> IntegrationsResource: return IntegrationsResource(self) + @cached_property + def documents(self) -> DocumentsResource: + from .resources.documents import DocumentsResource + + return DocumentsResource(self) + + @cached_property + def ads(self) -> AdsResource: + from .resources.ads import AdsResource + + return AdsResource(self) + @cached_property def with_raw_response(self) -> ProfoundWithRawResponse: return ProfoundWithRawResponse(self) @@ -486,6 +511,18 @@ def integrations(self) -> AsyncIntegrationsResource: return AsyncIntegrationsResource(self) + @cached_property + def documents(self) -> AsyncDocumentsResource: + from .resources.documents import AsyncDocumentsResource + + return AsyncDocumentsResource(self) + + @cached_property + def ads(self) -> AsyncAdsResource: + from .resources.ads import AsyncAdsResource + + return AsyncAdsResource(self) + @cached_property def with_raw_response(self) -> AsyncProfoundWithRawResponse: return AsyncProfoundWithRawResponse(self) @@ -682,6 +719,18 @@ def integrations(self) -> integrations.IntegrationsResourceWithRawResponse: return IntegrationsResourceWithRawResponse(self._client.integrations) + @cached_property + def documents(self) -> documents.DocumentsResourceWithRawResponse: + from .resources.documents import DocumentsResourceWithRawResponse + + return DocumentsResourceWithRawResponse(self._client.documents) + + @cached_property + def ads(self) -> ads.AdsResourceWithRawResponse: + from .resources.ads import AdsResourceWithRawResponse + + return AdsResourceWithRawResponse(self._client.ads) + class AsyncProfoundWithRawResponse: _client: AsyncProfound @@ -737,6 +786,18 @@ def integrations(self) -> integrations.AsyncIntegrationsResourceWithRawResponse: return AsyncIntegrationsResourceWithRawResponse(self._client.integrations) + @cached_property + def documents(self) -> documents.AsyncDocumentsResourceWithRawResponse: + from .resources.documents import AsyncDocumentsResourceWithRawResponse + + return AsyncDocumentsResourceWithRawResponse(self._client.documents) + + @cached_property + def ads(self) -> ads.AsyncAdsResourceWithRawResponse: + from .resources.ads import AsyncAdsResourceWithRawResponse + + return AsyncAdsResourceWithRawResponse(self._client.ads) + class ProfoundWithStreamedResponse: _client: Profound @@ -792,6 +853,18 @@ def integrations(self) -> integrations.IntegrationsResourceWithStreamingResponse return IntegrationsResourceWithStreamingResponse(self._client.integrations) + @cached_property + def documents(self) -> documents.DocumentsResourceWithStreamingResponse: + from .resources.documents import DocumentsResourceWithStreamingResponse + + return DocumentsResourceWithStreamingResponse(self._client.documents) + + @cached_property + def ads(self) -> ads.AdsResourceWithStreamingResponse: + from .resources.ads import AdsResourceWithStreamingResponse + + return AdsResourceWithStreamingResponse(self._client.ads) + class AsyncProfoundWithStreamedResponse: _client: AsyncProfound @@ -847,6 +920,18 @@ def integrations(self) -> integrations.AsyncIntegrationsResourceWithStreamingRes return AsyncIntegrationsResourceWithStreamingResponse(self._client.integrations) + @cached_property + def documents(self) -> documents.AsyncDocumentsResourceWithStreamingResponse: + from .resources.documents import AsyncDocumentsResourceWithStreamingResponse + + return AsyncDocumentsResourceWithStreamingResponse(self._client.documents) + + @cached_property + def ads(self) -> ads.AsyncAdsResourceWithStreamingResponse: + from .resources.ads import AsyncAdsResourceWithStreamingResponse + + return AsyncAdsResourceWithStreamingResponse(self._client.ads) + Client = Profound diff --git a/src/profound/resources/__init__.py b/src/profound/resources/__init__.py index d46f886e..43029334 100644 --- a/src/profound/resources/__init__.py +++ b/src/profound/resources/__init__.py @@ -1,5 +1,13 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +from .ads import ( + AdsResource, + AsyncAdsResource, + AdsResourceWithRawResponse, + AsyncAdsResourceWithRawResponse, + AdsResourceWithStreamingResponse, + AsyncAdsResourceWithStreamingResponse, +) from .agents import ( AgentsResource, AsyncAgentsResource, @@ -40,6 +48,14 @@ ProjectsResourceWithStreamingResponse, AsyncProjectsResourceWithStreamingResponse, ) +from .documents import ( + DocumentsResource, + AsyncDocumentsResource, + DocumentsResourceWithRawResponse, + AsyncDocumentsResourceWithRawResponse, + DocumentsResourceWithStreamingResponse, + AsyncDocumentsResourceWithStreamingResponse, +) from .integrations import ( IntegrationsResource, AsyncIntegrationsResource, @@ -114,4 +130,16 @@ "AsyncIntegrationsResourceWithRawResponse", "IntegrationsResourceWithStreamingResponse", "AsyncIntegrationsResourceWithStreamingResponse", + "DocumentsResource", + "AsyncDocumentsResource", + "DocumentsResourceWithRawResponse", + "AsyncDocumentsResourceWithRawResponse", + "DocumentsResourceWithStreamingResponse", + "AsyncDocumentsResourceWithStreamingResponse", + "AdsResource", + "AsyncAdsResource", + "AdsResourceWithRawResponse", + "AsyncAdsResourceWithRawResponse", + "AdsResourceWithStreamingResponse", + "AsyncAdsResourceWithStreamingResponse", ] diff --git a/src/profound/resources/ads/__init__.py b/src/profound/resources/ads/__init__.py new file mode 100644 index 00000000..d1321761 --- /dev/null +++ b/src/profound/resources/ads/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .ads import ( + AdsResource, + AsyncAdsResource, + AdsResourceWithRawResponse, + AsyncAdsResourceWithRawResponse, + AdsResourceWithStreamingResponse, + AsyncAdsResourceWithStreamingResponse, +) +from .openai_ads import ( + OpenAIAdsResource, + AsyncOpenAIAdsResource, + OpenAIAdsResourceWithRawResponse, + AsyncOpenAIAdsResourceWithRawResponse, + OpenAIAdsResourceWithStreamingResponse, + AsyncOpenAIAdsResourceWithStreamingResponse, +) + +__all__ = [ + "OpenAIAdsResource", + "AsyncOpenAIAdsResource", + "OpenAIAdsResourceWithRawResponse", + "AsyncOpenAIAdsResourceWithRawResponse", + "OpenAIAdsResourceWithStreamingResponse", + "AsyncOpenAIAdsResourceWithStreamingResponse", + "AdsResource", + "AsyncAdsResource", + "AdsResourceWithRawResponse", + "AsyncAdsResourceWithRawResponse", + "AdsResourceWithStreamingResponse", + "AsyncAdsResourceWithStreamingResponse", +] diff --git a/src/profound/resources/ads/ads.py b/src/profound/resources/ads/ads.py new file mode 100644 index 00000000..70838705 --- /dev/null +++ b/src/profound/resources/ads/ads.py @@ -0,0 +1,102 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from .openai_ads.openai_ads import ( + OpenAIAdsResource, + AsyncOpenAIAdsResource, + OpenAIAdsResourceWithRawResponse, + AsyncOpenAIAdsResourceWithRawResponse, + OpenAIAdsResourceWithStreamingResponse, + AsyncOpenAIAdsResourceWithStreamingResponse, +) + +__all__ = ["AdsResource", "AsyncAdsResource"] + + +class AdsResource(SyncAPIResource): + @cached_property + def openai_ads(self) -> OpenAIAdsResource: + return OpenAIAdsResource(self._client) + + @cached_property + def with_raw_response(self) -> AdsResourceWithRawResponse: + """ + 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/cooper-square-technologies/profound-python-sdk#accessing-raw-response-data-eg-headers + """ + return AdsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AdsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cooper-square-technologies/profound-python-sdk#with_streaming_response + """ + return AdsResourceWithStreamingResponse(self) + + +class AsyncAdsResource(AsyncAPIResource): + @cached_property + def openai_ads(self) -> AsyncOpenAIAdsResource: + return AsyncOpenAIAdsResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncAdsResourceWithRawResponse: + """ + 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/cooper-square-technologies/profound-python-sdk#accessing-raw-response-data-eg-headers + """ + return AsyncAdsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncAdsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cooper-square-technologies/profound-python-sdk#with_streaming_response + """ + return AsyncAdsResourceWithStreamingResponse(self) + + +class AdsResourceWithRawResponse: + def __init__(self, ads: AdsResource) -> None: + self._ads = ads + + @cached_property + def openai_ads(self) -> OpenAIAdsResourceWithRawResponse: + return OpenAIAdsResourceWithRawResponse(self._ads.openai_ads) + + +class AsyncAdsResourceWithRawResponse: + def __init__(self, ads: AsyncAdsResource) -> None: + self._ads = ads + + @cached_property + def openai_ads(self) -> AsyncOpenAIAdsResourceWithRawResponse: + return AsyncOpenAIAdsResourceWithRawResponse(self._ads.openai_ads) + + +class AdsResourceWithStreamingResponse: + def __init__(self, ads: AdsResource) -> None: + self._ads = ads + + @cached_property + def openai_ads(self) -> OpenAIAdsResourceWithStreamingResponse: + return OpenAIAdsResourceWithStreamingResponse(self._ads.openai_ads) + + +class AsyncAdsResourceWithStreamingResponse: + def __init__(self, ads: AsyncAdsResource) -> None: + self._ads = ads + + @cached_property + def openai_ads(self) -> AsyncOpenAIAdsResourceWithStreamingResponse: + return AsyncOpenAIAdsResourceWithStreamingResponse(self._ads.openai_ads) diff --git a/src/profound/resources/ads/openai_ads/__init__.py b/src/profound/resources/ads/openai_ads/__init__.py new file mode 100644 index 00000000..553f2b0c --- /dev/null +++ b/src/profound/resources/ads/openai_ads/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .ad_account import ( + AdAccountResource, + AsyncAdAccountResource, + AdAccountResourceWithRawResponse, + AsyncAdAccountResourceWithRawResponse, + AdAccountResourceWithStreamingResponse, + AsyncAdAccountResourceWithStreamingResponse, +) +from .openai_ads import ( + OpenAIAdsResource, + AsyncOpenAIAdsResource, + OpenAIAdsResourceWithRawResponse, + AsyncOpenAIAdsResourceWithRawResponse, + OpenAIAdsResourceWithStreamingResponse, + AsyncOpenAIAdsResourceWithStreamingResponse, +) + +__all__ = [ + "AdAccountResource", + "AsyncAdAccountResource", + "AdAccountResourceWithRawResponse", + "AsyncAdAccountResourceWithRawResponse", + "AdAccountResourceWithStreamingResponse", + "AsyncAdAccountResourceWithStreamingResponse", + "OpenAIAdsResource", + "AsyncOpenAIAdsResource", + "OpenAIAdsResourceWithRawResponse", + "AsyncOpenAIAdsResourceWithRawResponse", + "OpenAIAdsResourceWithStreamingResponse", + "AsyncOpenAIAdsResourceWithStreamingResponse", +] diff --git a/src/profound/resources/ads/openai_ads/ad_account.py b/src/profound/resources/ads/openai_ads/ad_account.py new file mode 100644 index 00000000..eaf8fb74 --- /dev/null +++ b/src/profound/resources/ads/openai_ads/ad_account.py @@ -0,0 +1,244 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Literal + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, 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.ads.openai_ads import ad_account_retrieve_insights_params +from ....types.ads.openai_ads.ad_account_retrieve_insights_response import AdAccountRetrieveInsightsResponse + +__all__ = ["AdAccountResource", "AsyncAdAccountResource"] + + +class AdAccountResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> AdAccountResourceWithRawResponse: + """ + 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/cooper-square-technologies/profound-python-sdk#accessing-raw-response-data-eg-headers + """ + return AdAccountResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AdAccountResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cooper-square-technologies/profound-python-sdk#with_streaming_response + """ + return AdAccountResourceWithStreamingResponse(self) + + def retrieve_insights( + self, + *, + after: Optional[str] | Omit = omit, + aggregation_level: Optional[Literal["ad_account", "campaign", "ad_group", "ad"]] | Omit = omit, + before: Optional[str] | Omit = omit, + limit: Optional[int] | Omit = omit, + organization_id: Optional[str] | Omit = omit, + time_granularity: Optional[Literal["hourly", "daily", "monthly", "none"]] | Omit = omit, + time_ranges: Optional[SequenceNotStr[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, + ) -> AdAccountRetrieveInsightsResponse: + """ + Get ad account insights for the organization's OpenAI Ads partner brand. + + `aggregation_level=campaign` returns one row per campaign (with `campaign_id` / + `campaign_name` and all metrics), so every campaign's insights come back in a + single call; `time_granularity=daily` gives per-day rows (e.g. daily spend). + + Args: + after: Return items after this ID (forward pagination). + + aggregation_level: Row entity for the insights breakdown. `campaign` returns one row per campaign. + + before: Return items before this ID (backward pagination). + + limit: Maximum rows to return. + + organization_id: Organization scope for API keys that can access multiple organizations. + + time_granularity: Time bucket for the rows; `none` or omitted returns totals over the whole range. + + time_ranges: Time ranges as JSON objects, e.g. + `{"type": "date_range", "since": "2026-07-01", "until": "2026-07-18"}`. + + 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( + "/v1/ads/openai-ads/ad-account/insights", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "after": after, + "aggregation_level": aggregation_level, + "before": before, + "limit": limit, + "organization_id": organization_id, + "time_granularity": time_granularity, + "time_ranges": time_ranges, + }, + ad_account_retrieve_insights_params.AdAccountRetrieveInsightsParams, + ), + ), + cast_to=AdAccountRetrieveInsightsResponse, + ) + + +class AsyncAdAccountResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncAdAccountResourceWithRawResponse: + """ + 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/cooper-square-technologies/profound-python-sdk#accessing-raw-response-data-eg-headers + """ + return AsyncAdAccountResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncAdAccountResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cooper-square-technologies/profound-python-sdk#with_streaming_response + """ + return AsyncAdAccountResourceWithStreamingResponse(self) + + async def retrieve_insights( + self, + *, + after: Optional[str] | Omit = omit, + aggregation_level: Optional[Literal["ad_account", "campaign", "ad_group", "ad"]] | Omit = omit, + before: Optional[str] | Omit = omit, + limit: Optional[int] | Omit = omit, + organization_id: Optional[str] | Omit = omit, + time_granularity: Optional[Literal["hourly", "daily", "monthly", "none"]] | Omit = omit, + time_ranges: Optional[SequenceNotStr[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, + ) -> AdAccountRetrieveInsightsResponse: + """ + Get ad account insights for the organization's OpenAI Ads partner brand. + + `aggregation_level=campaign` returns one row per campaign (with `campaign_id` / + `campaign_name` and all metrics), so every campaign's insights come back in a + single call; `time_granularity=daily` gives per-day rows (e.g. daily spend). + + Args: + after: Return items after this ID (forward pagination). + + aggregation_level: Row entity for the insights breakdown. `campaign` returns one row per campaign. + + before: Return items before this ID (backward pagination). + + limit: Maximum rows to return. + + organization_id: Organization scope for API keys that can access multiple organizations. + + time_granularity: Time bucket for the rows; `none` or omitted returns totals over the whole range. + + time_ranges: Time ranges as JSON objects, e.g. + `{"type": "date_range", "since": "2026-07-01", "until": "2026-07-18"}`. + + 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( + "/v1/ads/openai-ads/ad-account/insights", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "after": after, + "aggregation_level": aggregation_level, + "before": before, + "limit": limit, + "organization_id": organization_id, + "time_granularity": time_granularity, + "time_ranges": time_ranges, + }, + ad_account_retrieve_insights_params.AdAccountRetrieveInsightsParams, + ), + ), + cast_to=AdAccountRetrieveInsightsResponse, + ) + + +class AdAccountResourceWithRawResponse: + def __init__(self, ad_account: AdAccountResource) -> None: + self._ad_account = ad_account + + self.retrieve_insights = to_raw_response_wrapper( + ad_account.retrieve_insights, + ) + + +class AsyncAdAccountResourceWithRawResponse: + def __init__(self, ad_account: AsyncAdAccountResource) -> None: + self._ad_account = ad_account + + self.retrieve_insights = async_to_raw_response_wrapper( + ad_account.retrieve_insights, + ) + + +class AdAccountResourceWithStreamingResponse: + def __init__(self, ad_account: AdAccountResource) -> None: + self._ad_account = ad_account + + self.retrieve_insights = to_streamed_response_wrapper( + ad_account.retrieve_insights, + ) + + +class AsyncAdAccountResourceWithStreamingResponse: + def __init__(self, ad_account: AsyncAdAccountResource) -> None: + self._ad_account = ad_account + + self.retrieve_insights = async_to_streamed_response_wrapper( + ad_account.retrieve_insights, + ) diff --git a/src/profound/resources/ads/openai_ads/openai_ads.py b/src/profound/resources/ads/openai_ads/openai_ads.py new file mode 100644 index 00000000..c964d5af --- /dev/null +++ b/src/profound/resources/ads/openai_ads/openai_ads.py @@ -0,0 +1,102 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from ...._compat import cached_property +from .ad_account import ( + AdAccountResource, + AsyncAdAccountResource, + AdAccountResourceWithRawResponse, + AsyncAdAccountResourceWithRawResponse, + AdAccountResourceWithStreamingResponse, + AsyncAdAccountResourceWithStreamingResponse, +) +from ...._resource import SyncAPIResource, AsyncAPIResource + +__all__ = ["OpenAIAdsResource", "AsyncOpenAIAdsResource"] + + +class OpenAIAdsResource(SyncAPIResource): + @cached_property + def ad_account(self) -> AdAccountResource: + return AdAccountResource(self._client) + + @cached_property + def with_raw_response(self) -> OpenAIAdsResourceWithRawResponse: + """ + 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/cooper-square-technologies/profound-python-sdk#accessing-raw-response-data-eg-headers + """ + return OpenAIAdsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> OpenAIAdsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cooper-square-technologies/profound-python-sdk#with_streaming_response + """ + return OpenAIAdsResourceWithStreamingResponse(self) + + +class AsyncOpenAIAdsResource(AsyncAPIResource): + @cached_property + def ad_account(self) -> AsyncAdAccountResource: + return AsyncAdAccountResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncOpenAIAdsResourceWithRawResponse: + """ + 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/cooper-square-technologies/profound-python-sdk#accessing-raw-response-data-eg-headers + """ + return AsyncOpenAIAdsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncOpenAIAdsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cooper-square-technologies/profound-python-sdk#with_streaming_response + """ + return AsyncOpenAIAdsResourceWithStreamingResponse(self) + + +class OpenAIAdsResourceWithRawResponse: + def __init__(self, openai_ads: OpenAIAdsResource) -> None: + self._openai_ads = openai_ads + + @cached_property + def ad_account(self) -> AdAccountResourceWithRawResponse: + return AdAccountResourceWithRawResponse(self._openai_ads.ad_account) + + +class AsyncOpenAIAdsResourceWithRawResponse: + def __init__(self, openai_ads: AsyncOpenAIAdsResource) -> None: + self._openai_ads = openai_ads + + @cached_property + def ad_account(self) -> AsyncAdAccountResourceWithRawResponse: + return AsyncAdAccountResourceWithRawResponse(self._openai_ads.ad_account) + + +class OpenAIAdsResourceWithStreamingResponse: + def __init__(self, openai_ads: OpenAIAdsResource) -> None: + self._openai_ads = openai_ads + + @cached_property + def ad_account(self) -> AdAccountResourceWithStreamingResponse: + return AdAccountResourceWithStreamingResponse(self._openai_ads.ad_account) + + +class AsyncOpenAIAdsResourceWithStreamingResponse: + def __init__(self, openai_ads: AsyncOpenAIAdsResource) -> None: + self._openai_ads = openai_ads + + @cached_property + def ad_account(self) -> AsyncAdAccountResourceWithStreamingResponse: + return AsyncAdAccountResourceWithStreamingResponse(self._openai_ads.ad_account) diff --git a/src/profound/resources/documents.py b/src/profound/resources/documents.py new file mode 100644 index 00000000..d052cee1 --- /dev/null +++ b/src/profound/resources/documents.py @@ -0,0 +1,227 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ..types import document_create_params +from .._types import Body, Query, Headers, NotGiven, 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.document_create_response import DocumentCreateResponse + +__all__ = ["DocumentsResource", "AsyncDocumentsResource"] + + +class DocumentsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> DocumentsResourceWithRawResponse: + """ + 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/cooper-square-technologies/profound-python-sdk#accessing-raw-response-data-eg-headers + """ + return DocumentsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> DocumentsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cooper-square-technologies/profound-python-sdk#with_streaming_response + """ + return DocumentsResourceWithStreamingResponse(self) + + def create( + self, + *, + id: str, + content_markdown: str, + name: str, + organization_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, + ) -> DocumentCreateResponse: + """ + Create a Profound document with markdown content. + + `organization_id` is required and you must be a member of it. You choose the + document's `id`, and creation is idempotent on it: repeating the request returns + the existing document rather than creating a second one. + + New documents are visible only to their creator; share them from the Profound + app, or open one with the `url` in the response. + + Args: + id: + ID for the new document, chosen by you. Creation is idempotent on this ID: + repeating a request with the same ID returns the existing document instead of + creating a second one, so a retry after a network error is safe. + + content_markdown: Initial document body as markdown. Must be non-empty. Rendered into the + collaborative editor, so the result is real editable content, not a stored blob. + + name: Title for the document. Must be non-empty. + + organization_id: ID of the organization that will own the document. Required — Profound API keys + are user-scoped, so the owning organization must be chosen explicitly. The + caller must be a member of this organization. + + 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/documents", + body=maybe_transform( + { + "id": id, + "content_markdown": content_markdown, + "name": name, + "organization_id": organization_id, + }, + document_create_params.DocumentCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=DocumentCreateResponse, + ) + + +class AsyncDocumentsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncDocumentsResourceWithRawResponse: + """ + 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/cooper-square-technologies/profound-python-sdk#accessing-raw-response-data-eg-headers + """ + return AsyncDocumentsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncDocumentsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cooper-square-technologies/profound-python-sdk#with_streaming_response + """ + return AsyncDocumentsResourceWithStreamingResponse(self) + + async def create( + self, + *, + id: str, + content_markdown: str, + name: str, + organization_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, + ) -> DocumentCreateResponse: + """ + Create a Profound document with markdown content. + + `organization_id` is required and you must be a member of it. You choose the + document's `id`, and creation is idempotent on it: repeating the request returns + the existing document rather than creating a second one. + + New documents are visible only to their creator; share them from the Profound + app, or open one with the `url` in the response. + + Args: + id: + ID for the new document, chosen by you. Creation is idempotent on this ID: + repeating a request with the same ID returns the existing document instead of + creating a second one, so a retry after a network error is safe. + + content_markdown: Initial document body as markdown. Must be non-empty. Rendered into the + collaborative editor, so the result is real editable content, not a stored blob. + + name: Title for the document. Must be non-empty. + + organization_id: ID of the organization that will own the document. Required — Profound API keys + are user-scoped, so the owning organization must be chosen explicitly. The + caller must be a member of this organization. + + 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/documents", + body=await async_maybe_transform( + { + "id": id, + "content_markdown": content_markdown, + "name": name, + "organization_id": organization_id, + }, + document_create_params.DocumentCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=DocumentCreateResponse, + ) + + +class DocumentsResourceWithRawResponse: + def __init__(self, documents: DocumentsResource) -> None: + self._documents = documents + + self.create = to_raw_response_wrapper( + documents.create, + ) + + +class AsyncDocumentsResourceWithRawResponse: + def __init__(self, documents: AsyncDocumentsResource) -> None: + self._documents = documents + + self.create = async_to_raw_response_wrapper( + documents.create, + ) + + +class DocumentsResourceWithStreamingResponse: + def __init__(self, documents: DocumentsResource) -> None: + self._documents = documents + + self.create = to_streamed_response_wrapper( + documents.create, + ) + + +class AsyncDocumentsResourceWithStreamingResponse: + def __init__(self, documents: AsyncDocumentsResource) -> None: + self._documents = documents + + self.create = async_to_streamed_response_wrapper( + documents.create, + ) diff --git a/src/profound/types/__init__.py b/src/profound/types/__init__.py index eb487ef0..ca83ccce 100644 --- a/src/profound/types/__init__.py +++ b/src/profound/types/__init__.py @@ -42,6 +42,7 @@ from .prompt_answers_params import PromptAnswersParams as PromptAnswersParams from .tag_name_filter_param import TagNameFilterParam as TagNameFilterParam from .agent_publish_response import AgentPublishResponse as AgentPublishResponse +from .document_create_params import DocumentCreateParams as DocumentCreateParams from .project_archive_params import ProjectArchiveParams as ProjectArchiveParams from .prompt_id_filter_param import PromptIDFilterParam as PromptIDFilterParam from .agent_retrieve_response import AgentRetrieveResponse as AgentRetrieveResponse @@ -52,6 +53,7 @@ from .report_citations_params import ReportCitationsParams as ReportCitationsParams from .report_sentiment_params import ReportSentimentParams as ReportSentimentParams from .topic_name_filter_param import TopicNameFilterParam as TopicNameFilterParam +from .document_create_response import DocumentCreateResponse as DocumentCreateResponse from .persona_profile_behavior import PersonaProfileBehavior as PersonaProfileBehavior from .project_archive_response import ProjectArchiveResponse as ProjectArchiveResponse from .project_unarchive_params import ProjectUnarchiveParams as ProjectUnarchiveParams diff --git a/src/profound/types/ads/__init__.py b/src/profound/types/ads/__init__.py new file mode 100644 index 00000000..f8ee8b14 --- /dev/null +++ b/src/profound/types/ads/__init__.py @@ -0,0 +1,3 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations diff --git a/src/profound/types/ads/openai_ads/__init__.py b/src/profound/types/ads/openai_ads/__init__.py new file mode 100644 index 00000000..c0aa321e --- /dev/null +++ b/src/profound/types/ads/openai_ads/__init__.py @@ -0,0 +1,8 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .ad_account_retrieve_insights_params import AdAccountRetrieveInsightsParams as AdAccountRetrieveInsightsParams +from .ad_account_retrieve_insights_response import ( + AdAccountRetrieveInsightsResponse as AdAccountRetrieveInsightsResponse, +) diff --git a/src/profound/types/ads/openai_ads/ad_account_retrieve_insights_params.py b/src/profound/types/ads/openai_ads/ad_account_retrieve_insights_params.py new file mode 100644 index 00000000..e9315a3c --- /dev/null +++ b/src/profound/types/ads/openai_ads/ad_account_retrieve_insights_params.py @@ -0,0 +1,38 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Literal, TypedDict + +from ...._types import SequenceNotStr + +__all__ = ["AdAccountRetrieveInsightsParams"] + + +class AdAccountRetrieveInsightsParams(TypedDict, total=False): + after: Optional[str] + """Return items after this ID (forward pagination).""" + + aggregation_level: Optional[Literal["ad_account", "campaign", "ad_group", "ad"]] + """Row entity for the insights breakdown. `campaign` returns one row per campaign.""" + + before: Optional[str] + """Return items before this ID (backward pagination).""" + + limit: Optional[int] + """Maximum rows to return.""" + + organization_id: Optional[str] + """Organization scope for API keys that can access multiple organizations.""" + + time_granularity: Optional[Literal["hourly", "daily", "monthly", "none"]] + """ + Time bucket for the rows; `none` or omitted returns totals over the whole range. + """ + + time_ranges: Optional[SequenceNotStr[str]] + """Time ranges as JSON objects, e.g. + + `{"type": "date_range", "since": "2026-07-01", "until": "2026-07-18"}`. + """ diff --git a/src/profound/types/ads/openai_ads/ad_account_retrieve_insights_response.py b/src/profound/types/ads/openai_ads/ad_account_retrieve_insights_response.py new file mode 100644 index 00000000..c1536aa1 --- /dev/null +++ b/src/profound/types/ads/openai_ads/ad_account_retrieve_insights_response.py @@ -0,0 +1,86 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from ...._models import BaseModel + +__all__ = ["AdAccountRetrieveInsightsResponse", "Data"] + + +class Data(BaseModel): + """One insights row; the entity it describes follows `aggregation_level`. + + Time bounds are present when a `time_granularity` is requested (one row per + time bucket); the entity id/name fields (`campaign_*`, `ad_group_*`, `ad_*`) + are present when rows are broken down by that entity. + """ + + id: str + """Row ID.""" + + ad_group_id: Optional[str] = None + """Ad group ID for ad_group-level rows.""" + + ad_group_name: Optional[str] = None + """Ad group name for ad_group-level rows.""" + + ad_id: Optional[str] = None + """Ad ID for ad-level rows.""" + + ad_name: Optional[str] = None + """Ad name for ad-level rows.""" + + campaign_id: Optional[str] = None + """Campaign ID for campaign-level rows.""" + + campaign_name: Optional[str] = None + """Campaign name for campaign-level rows.""" + + clicks: Optional[int] = None + """Clicks.""" + + cpc: Optional[float] = None + """Cost per click.""" + + cpm: Optional[float] = None + """Cost per thousand impressions.""" + + ctr: Optional[float] = None + """Click-through rate.""" + + end_time: Optional[int] = None + """Bucket end (unix seconds).""" + + impressions: Optional[int] = None + """Impressions.""" + + readable_time: Optional[str] = None + """Human-readable time bucket.""" + + spend: Optional[float] = None + """Spend in the ad account's currency units.""" + + start_time: Optional[int] = None + """Bucket start (unix seconds).""" + + timezone: Optional[str] = None + """Timezone of the time bucket.""" + + +class AdAccountRetrieveInsightsResponse(BaseModel): + """Cursor-paginated insights, mirroring the OpenAI Ads insights envelope.""" + + data: List[Data] + """Insight rows.""" + + count: Optional[int] = None + """Total row count, when reported upstream.""" + + first_id: Optional[str] = None + """ID of the first item; pass as `before` to page back.""" + + has_more: Optional[bool] = None + """Whether more items are available.""" + + last_id: Optional[str] = None + """ID of the last item; pass as `after` to page forward.""" diff --git a/src/profound/types/document_create_params.py b/src/profound/types/document_create_params.py new file mode 100644 index 00000000..7013a26e --- /dev/null +++ b/src/profound/types/document_create_params.py @@ -0,0 +1,34 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["DocumentCreateParams"] + + +class DocumentCreateParams(TypedDict, total=False): + id: Required[str] + """ID for the new document, chosen by you. + + Creation is idempotent on this ID: repeating a request with the same ID returns + the existing document instead of creating a second one, so a retry after a + network error is safe. + """ + + content_markdown: Required[str] + """Initial document body as markdown. + + Must be non-empty. Rendered into the collaborative editor, so the result is real + editable content, not a stored blob. + """ + + name: Required[str] + """Title for the document. Must be non-empty.""" + + organization_id: Required[str] + """ID of the organization that will own the document. + + Required — Profound API keys are user-scoped, so the owning organization must be + chosen explicitly. The caller must be a member of this organization. + """ diff --git a/src/profound/types/document_create_response.py b/src/profound/types/document_create_response.py new file mode 100644 index 00000000..8517f871 --- /dev/null +++ b/src/profound/types/document_create_response.py @@ -0,0 +1,34 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from datetime import datetime +from typing_extensions import Literal + +from .._models import BaseModel + +__all__ = ["DocumentCreateResponse"] + + +class DocumentCreateResponse(BaseModel): + """A Profound document.""" + + id: str + """The document's ID.""" + + created_at: datetime + """When the document was created.""" + + name: str + """The document's title.""" + + updated_at: datetime + """When the document was last modified. + + Seeding the initial content counts, so a freshly created document is normally + modified a moment after it was created. + """ + + url: str + """Link to open the document in the Profound app.""" + + visibility: Literal["invited_only", "organization"] + """General access scope. New documents are `invited_only`.""" diff --git a/tests/api_resources/ads/__init__.py b/tests/api_resources/ads/__init__.py new file mode 100644 index 00000000..fd8019a9 --- /dev/null +++ b/tests/api_resources/ads/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/ads/openai_ads/__init__.py b/tests/api_resources/ads/openai_ads/__init__.py new file mode 100644 index 00000000..fd8019a9 --- /dev/null +++ b/tests/api_resources/ads/openai_ads/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/ads/openai_ads/test_ad_account.py b/tests/api_resources/ads/openai_ads/test_ad_account.py new file mode 100644 index 00000000..50133000 --- /dev/null +++ b/tests/api_resources/ads/openai_ads/test_ad_account.py @@ -0,0 +1,108 @@ +# 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 profound import Profound, AsyncProfound +from tests.utils import assert_matches_type +from profound.types.ads.openai_ads import AdAccountRetrieveInsightsResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestAdAccount: + 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_retrieve_insights(self, client: Profound) -> None: + ad_account = client.ads.openai_ads.ad_account.retrieve_insights() + assert_matches_type(AdAccountRetrieveInsightsResponse, ad_account, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_retrieve_insights_with_all_params(self, client: Profound) -> None: + ad_account = client.ads.openai_ads.ad_account.retrieve_insights( + after="after", + aggregation_level="ad_account", + before="before", + limit=1, + organization_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + time_granularity="hourly", + time_ranges=["string", "string"], + ) + assert_matches_type(AdAccountRetrieveInsightsResponse, ad_account, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_retrieve_insights(self, client: Profound) -> None: + response = client.ads.openai_ads.ad_account.with_raw_response.retrieve_insights() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + ad_account = response.parse() + assert_matches_type(AdAccountRetrieveInsightsResponse, ad_account, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_retrieve_insights(self, client: Profound) -> None: + with client.ads.openai_ads.ad_account.with_streaming_response.retrieve_insights() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + ad_account = response.parse() + assert_matches_type(AdAccountRetrieveInsightsResponse, ad_account, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncAdAccount: + 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_retrieve_insights(self, async_client: AsyncProfound) -> None: + ad_account = await async_client.ads.openai_ads.ad_account.retrieve_insights() + assert_matches_type(AdAccountRetrieveInsightsResponse, ad_account, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_retrieve_insights_with_all_params(self, async_client: AsyncProfound) -> None: + ad_account = await async_client.ads.openai_ads.ad_account.retrieve_insights( + after="after", + aggregation_level="ad_account", + before="before", + limit=1, + organization_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + time_granularity="hourly", + time_ranges=["string", "string"], + ) + assert_matches_type(AdAccountRetrieveInsightsResponse, ad_account, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_retrieve_insights(self, async_client: AsyncProfound) -> None: + response = await async_client.ads.openai_ads.ad_account.with_raw_response.retrieve_insights() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + ad_account = await response.parse() + assert_matches_type(AdAccountRetrieveInsightsResponse, ad_account, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_retrieve_insights(self, async_client: AsyncProfound) -> None: + async with async_client.ads.openai_ads.ad_account.with_streaming_response.retrieve_insights() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + ad_account = await response.parse() + assert_matches_type(AdAccountRetrieveInsightsResponse, ad_account, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_documents.py b/tests/api_resources/test_documents.py new file mode 100644 index 00000000..32d36b28 --- /dev/null +++ b/tests/api_resources/test_documents.py @@ -0,0 +1,110 @@ +# 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 profound import Profound, AsyncProfound +from tests.utils import assert_matches_type +from profound.types import DocumentCreateResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestDocuments: + 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: Profound) -> None: + document = client.documents.create( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + content_markdown="x", + name="x", + organization_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(DocumentCreateResponse, document, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_create(self, client: Profound) -> None: + response = client.documents.with_raw_response.create( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + content_markdown="x", + name="x", + organization_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + document = response.parse() + assert_matches_type(DocumentCreateResponse, document, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_create(self, client: Profound) -> None: + with client.documents.with_streaming_response.create( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + content_markdown="x", + name="x", + organization_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + document = response.parse() + assert_matches_type(DocumentCreateResponse, document, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncDocuments: + 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: AsyncProfound) -> None: + document = await async_client.documents.create( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + content_markdown="x", + name="x", + organization_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(DocumentCreateResponse, document, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_create(self, async_client: AsyncProfound) -> None: + response = await async_client.documents.with_raw_response.create( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + content_markdown="x", + name="x", + organization_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + document = await response.parse() + assert_matches_type(DocumentCreateResponse, document, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_create(self, async_client: AsyncProfound) -> None: + async with async_client.documents.with_streaming_response.create( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + content_markdown="x", + name="x", + organization_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + document = await response.parse() + assert_matches_type(DocumentCreateResponse, document, path=["response"]) + + assert cast(Any, response.is_closed) is True From 763f0a57142fbfbeb6c471ca8a03e51789ccd480 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 3 Aug 2026 15:17:28 +0000 Subject: [PATCH 11/12] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 8c2e2d45..f45bdb9a 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 104 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-dfea5ac8ff0b5b11ac1d8ad2079ecd3b70dc61860e7d084e98f362a578837d94.yml -openapi_spec_hash: 0f50b7862d9981f3837865b7e971bea7 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/profound/profound-5c4cb4f429880b66ddd5118a2efdbd8c4ca08b3f1568fd3f901bc3d89095f1b5.yml +openapi_spec_hash: 3e6b04641ef9981dc677a2f6899abb8a config_hash: 191a4ee80e1a76fd6ac596027c4ef244 From eb4cd9ab9a27cd2200ff1aa0f98beb238c9a31ea Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 3 Aug 2026 15:17:56 +0000 Subject: [PATCH 12/12] release: 0.56.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 9 +++++++++ pyproject.toml | 2 +- src/profound/_version.py | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index d940b600..87d3d84c 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.55.0" + ".": "0.56.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 20628def..bf37f874 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 0.56.0 (2026-08-03) + +Full Changelog: [v0.55.0...v0.56.0](https://github.com/cooper-square-technologies/profound-python-sdk/compare/v0.55.0...v0.56.0) + +### Features + +* **api:** api update ([6c38bfb](https://github.com/cooper-square-technologies/profound-python-sdk/commit/6c38bfbb3d9e564499611a33396c310d69e375e4)) +* **api:** manual updates ([29a4731](https://github.com/cooper-square-technologies/profound-python-sdk/commit/29a4731fd6d06e3d85a0c5aac22589d406126c6e)) + ## 0.55.0 (2026-07-30) Full Changelog: [v0.54.0...v0.55.0](https://github.com/cooper-square-technologies/profound-python-sdk/compare/v0.54.0...v0.55.0) diff --git a/pyproject.toml b/pyproject.toml index 9c36160a..0b776b8e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "profound" -version = "0.55.0" +version = "0.56.0" description = "The official Python library for the profound API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/profound/_version.py b/src/profound/_version.py index 08b468b7..0a80bd3b 100644 --- a/src/profound/_version.py +++ b/src/profound/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "profound" -__version__ = "0.55.0" # x-release-please-version +__version__ = "0.56.0" # x-release-please-version