diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock
index 777e0dd0..1e1c1655 100644
--- a/.speakeasy/gen.lock
+++ b/.speakeasy/gen.lock
@@ -1,12 +1,12 @@
lockVersion: 2.0.0
id: 3e3290ca-0ee8-4981-b1bc-14536048fa63
management:
- docChecksum: ba76322a279d357942029f1599c8ad4d
+ docChecksum: 11234d282481d3710e009ee7857573b0
docVersion: 0.9.0
- speakeasyVersion: 1.625.0
- generationVersion: 2.715.0
- releaseVersion: 0.8.0
- configChecksum: 161090a0932a0c96a5f416fa490eb541
+ speakeasyVersion: 1.628.2
+ generationVersion: 2.716.3
+ releaseVersion: 0.8.1
+ configChecksum: e18f0607a86d7edb15c7ab3679dee60e
repoURL: https://github.com/gleanwork/api-client-python.git
installationURL: https://github.com/gleanwork/api-client-python.git
published: true
@@ -37,8 +37,8 @@ features:
responseFormat: 1.0.1
retries: 3.0.2
sdkHooks: 1.1.0
- tests: 1.19.4
- unions: 3.0.4
+ tests: 1.19.5
+ unions: 3.0.5
uploadStreams: 1.0.0
generatedFiles:
- .devcontainer/README.md
@@ -2702,4 +2702,6 @@ generatedTests:
editcollection: "2025-06-12T19:13:52-04:00"
createshortcut: "2025-06-12T19:13:52-04:00"
updateshortcut: "2025-06-12T19:13:52-04:00"
-releaseNotes: "## Python SDK Changes Detected:\n* `glean.client.documents.summarize()`: \n * `request.document_specs.[].[class]` **Changed** **Breaking** :warning:\n* `glean.client.documents.retrieve()`: \n * `request.document_specs.[].[class]` **Changed** **Breaking** :warning:\n * `response.documents.{}.[document].metadata.author.related_documents.[]` **Changed**\n* `glean.client.answers.create()`: \n * `request.data.added_roles.[]` **Changed** **Breaking** :warning:\n * `response.added_roles.[]` **Changed**\n* `glean.client.answers.update()`: \n * `request.added_roles.[]` **Changed** **Breaking** :warning:\n * `response.added_roles.[]` **Changed**\n* `glean.client.shortcuts.update()`: \n * `request.added_roles.[]` **Changed** **Breaking** :warning:\n * `response.shortcut.added_roles.[]` **Changed**\n* `glean.client.shortcuts.create()`: \n * `request.data.added_roles.[]` **Changed** **Breaking** :warning:\n * `response.shortcut.added_roles.[]` **Changed**\n* `glean.client.chat.create()`: \n * `request.messages.[]` **Changed** **Breaking** :warning:\n * `response.messages.[]` **Changed**\n* `glean.client.search.query()`: \n * `request.source_document.metadata.author.related_documents.[]` **Changed** **Breaking** :warning:\n * `response.results.[].structured_results.[].document.metadata` **Changed**\n* `glean.client.search.recommendations()`: \n * `request.source_document.metadata.author.related_documents.[]` **Changed** **Breaking** :warning:\n * `response.results.[].structured_results.[].document.metadata` **Changed**\n* `glean.client.search.query_as_admin()`: \n * `request.source_document.metadata.author.related_documents.[]` **Changed** **Breaking** :warning:\n * `response.results.[].structured_results.[].document.metadata` **Changed**\n* `glean.client.chat.create_stream()`: \n * `request.messages.[]` **Changed** **Breaking** :warning:\n* `glean.client.announcements.create()`: \n * `request.body.structured_list.[].document.metadata.author.related_documents.[]` **Changed** **Breaking** :warning:\n * `response.body.structured_list.[].document.metadata.author.related_documents.[]` **Changed**\n* `glean.client.collections.create()`: \n * `request.added_roles.[]` **Changed** **Breaking** :warning:\n * `response` **Changed** **Breaking** :warning:\n* `glean.client.announcements.update()`: \n * `request.body.structured_list.[].document.metadata.author.related_documents.[]` **Changed** **Breaking** :warning:\n * `response.body.structured_list.[].document.metadata.author.related_documents.[]` **Changed**\n* `glean.client.collections.update()`: \n * `request.added_roles.[]` **Changed** **Breaking** :warning:\n * `response.added_roles.[]` **Changed**\n* `glean.client.collections.add_items()`: `response.collection.added_roles.[]` **Changed**\n* `glean.client.search.autocomplete()`: `response.results.[].document.metadata.author.related_documents.[]` **Changed**\n* `glean.client.collections.list()`: `response.collections.[].added_roles.[]` **Changed**\n* `glean.client.collections.update_item()`: `response.collection.added_roles.[]` **Changed**\n* `glean.client.documents.retrieve_by_facets()`: `response.documents.[].metadata.author.related_documents.[]` **Changed**\n* `glean.client.collections.delete_item()`: `response.collection.added_roles.[]` **Changed**\n* `glean.client.insights.retrieve()`: `response.users.activity_insights.[].user.related_documents.[].query_suggestion` **Changed**\n* `glean.client.messages.retrieve()`: `response.search_response.results.[].structured_results.[].document.metadata` **Changed**\n* `glean.client.pins.update()`: `response.attribution.related_documents.[].query_suggestion` **Changed**\n* `glean.client.pins.retrieve()`: `response.pin.attribution.related_documents.[].query_suggestion` **Changed**\n* `glean.client.pins.list()`: `response.pins.[].attribution.related_documents.[].query_suggestion` **Changed**\n* `glean.client.pins.create()`: `response.attribution.related_documents.[].query_suggestion` **Changed**\n* `glean.client.chat.retrieve_files()`: `request.chat_id` **Added**\n* `glean.client.collections.retrieve()`: `response.collection.added_roles.[]` **Changed**\n* `glean.client.search.retrieve_feed()`: `response.results.[].primary_entry` **Changed**\n* `glean.client.chat.list()`: `response.chat_results.[].chat.created_by.related_documents.[].query_suggestion` **Changed**\n* `glean.client.chat.retrieve()`: `response.chat_result.chat` **Changed**\n* `glean.client.entities.list()`: `response.results.[].related_documents.[].query_suggestion` **Changed**\n* `glean.client.entities.read_people()`: `response.results.[].related_documents.[].query_suggestion` **Changed**\n* `glean.client.answers.list()`: `response.answer_results.[].answer.added_roles.[]` **Changed**\n* `glean.client.shortcuts.retrieve()`: `response.shortcut.added_roles.[]` **Changed**\n* `glean.client.shortcuts.list()`: `response.shortcuts.[].added_roles.[]` **Changed**\n* `glean.client.answers.retrieve()`: `response.answer_result.answer.added_roles.[]` **Changed**\n* `glean.client.verification.add_reminder()`: `response.metadata.last_verifier.related_documents.[].query_suggestion` **Changed**\n* `glean.client.verification.list()`: `response.documents.[].metadata.last_verifier.related_documents.[].query_suggestion` **Changed**\n* `glean.client.verification.verify()`: `response.metadata.last_verifier.related_documents.[].query_suggestion` **Changed**\n"
+releaseNotes: |
+ ## Python SDK Changes Detected:
+ * `glean.client.search.retrieve_feed()`: `response.results.[].primary_entry.digest.sections.[].channel_type` **Added**
diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml
index 7588e747..f2147a45 100644
--- a/.speakeasy/gen.yaml
+++ b/.speakeasy/gen.yaml
@@ -27,7 +27,7 @@ generation:
generateNewTests: true
skipResponseBodyAssertions: true
python:
- version: 0.8.0
+ version: 0.8.1
additionalDependencies:
dev: {}
main: {}
@@ -58,6 +58,7 @@ python:
shared: ""
webhooks: ""
inputModelSuffix: input
+ legacyPyright: true
maxMethodParams: 999
methodArguments: infer-optional-args
moduleName: glean.api_client
diff --git a/.speakeasy/glean-merged-spec.yaml b/.speakeasy/glean-merged-spec.yaml
index 7a87e86a..2114919e 100644
--- a/.speakeasy/glean-merged-spec.yaml
+++ b/.speakeasy/glean-merged-spec.yaml
@@ -9430,6 +9430,11 @@ components:
channelName:
type: string
description: Name of the channel (applicable for CHANNEL type sections). Used to display in the frontend.
+ channelType:
+ type: string
+ description: |
+ Channel visibility/type for CHANNEL sections. For Slack this is typically one of
+ PublicChannel, PrivateChannel. Omit if not applicable or unknown.
instanceId:
type: string
description: Instance identifier for the channel or workspace. Used for constructing channel URLs to display in the frontend.
diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock
index 4ba2a505..fdfbdad9 100644
--- a/.speakeasy/workflow.lock
+++ b/.speakeasy/workflow.lock
@@ -1,12 +1,12 @@
-speakeasyVersion: 1.625.0
+speakeasyVersion: 1.628.2
sources:
Glean API:
sourceNamespace: glean-api-specs
- sourceRevisionDigest: sha256:a9b49b3146d88faffb25761f988ab0445ed0366b84774a13d4754cb0eb7a3b9b
- sourceBlobDigest: sha256:4408853be9bce04865c08fd37b8c11320ffd3b79ef0c70ca8fa1791df0679b1f
+ sourceRevisionDigest: sha256:3dba87a7b61abaf1f2a6b645c2c9d1c5d79481f48ff3d57b2f1a864b8c8aa02f
+ sourceBlobDigest: sha256:49403d59f8446958ed5e813bbf322fda12ae91ed0991975bb0f24de0a189f74e
tags:
- latest
- - speakeasy-sdk-regen-1758751971
+ - speakeasy-sdk-regen-1758790482
Glean Client API:
sourceNamespace: glean-client-api
sourceRevisionDigest: sha256:4edc63ad559e4f2c9fb9ebf5edaaaaa9269f1874d271cfd84b441d6dacac43d2
@@ -17,10 +17,10 @@ targets:
glean:
source: Glean API
sourceNamespace: glean-api-specs
- sourceRevisionDigest: sha256:a9b49b3146d88faffb25761f988ab0445ed0366b84774a13d4754cb0eb7a3b9b
- sourceBlobDigest: sha256:4408853be9bce04865c08fd37b8c11320ffd3b79ef0c70ca8fa1791df0679b1f
+ sourceRevisionDigest: sha256:3dba87a7b61abaf1f2a6b645c2c9d1c5d79481f48ff3d57b2f1a864b8c8aa02f
+ sourceBlobDigest: sha256:49403d59f8446958ed5e813bbf322fda12ae91ed0991975bb0f24de0a189f74e
codeSamplesNamespace: glean-api-specs-python-code-samples
- codeSamplesRevisionDigest: sha256:98a13a63cdf737a90dd1b7477ea6c0ce8a80bbd62c3e5bdce09ca7d65585e69b
+ codeSamplesRevisionDigest: sha256:f2603f30ecbb58faccb490a39011e91f26cad10f137200df87cd2348bb82fe6a
workflow:
workflowVersion: 1.0.0
speakeasyVersion: latest
diff --git a/README.md b/README.md
index af4f21e2..da44e2a7 100644
--- a/README.md
+++ b/README.md
@@ -161,6 +161,7 @@ with Glean(
The same SDK client can also be used to make asynchronous requests by importing asyncio.
+
```python
# Asynchronous Example
import asyncio
@@ -218,6 +219,7 @@ with Glean(
The same SDK client can also be used to make asynchronous requests by importing asyncio.
+
```python
# Asynchronous Example
import asyncio
diff --git a/RELEASES.md b/RELEASES.md
index 36f4b16f..63b3a3a8 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -218,4 +218,14 @@ Based on:
### Generated
- [python v0.8.0] .
### Releases
-- [PyPI v0.8.0] https://pypi.org/project/glean/0.8.0 - .
\ No newline at end of file
+- [PyPI v0.8.0] https://pypi.org/project/glean/0.8.0 - .
+
+## 2025-09-25 08:54:18
+### Changes
+Based on:
+- OpenAPI Doc
+- Speakeasy CLI 1.628.2 (2.716.3) https://github.com/speakeasy-api/speakeasy
+### Generated
+- [python v0.8.1] .
+### Releases
+- [PyPI v0.8.1] https://pypi.org/project/glean/0.8.1 - .
\ No newline at end of file
diff --git a/USAGE.md b/USAGE.md
index b4ca16c7..13f153fa 100644
--- a/USAGE.md
+++ b/USAGE.md
@@ -26,6 +26,7 @@ with Glean(
The same SDK client can also be used to make asynchronous requests by importing asyncio.
+
```python
# Asynchronous Example
import asyncio
@@ -81,6 +82,7 @@ with Glean(
The same SDK client can also be used to make asynchronous requests by importing asyncio.
+
```python
# Asynchronous Example
import asyncio
diff --git a/docs/models/digestsection.md b/docs/models/digestsection.md
index 80a74c6f..f73def2b 100644
--- a/docs/models/digestsection.md
+++ b/docs/models/digestsection.md
@@ -3,12 +3,13 @@
## Fields
-| Field | Type | Required | Description |
-| ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
-| `id` | *str* | :heavy_check_mark: | Unique identifier for the digest section. |
-| `type` | [models.SectionType](../models/sectiontype.md) | :heavy_check_mark: | Type of the section. This defines how the section should be interpreted and rendered in the digest. |
-| `display_name` | *Optional[str]* | :heavy_minus_sign: | Human-readable name for the digest section. |
-| `channel_name` | *Optional[str]* | :heavy_minus_sign: | Name of the channel (applicable for CHANNEL type sections). Used to display in the frontend. |
-| `instance_id` | *Optional[str]* | :heavy_minus_sign: | Instance identifier for the channel or workspace. Used for constructing channel URLs to display in the frontend. |
-| `url` | *Optional[str]* | :heavy_minus_sign: | Optional URL for the digest section. Should be populated only if the section is a CHANNEL type section. |
-| `updates` | List[[models.DigestUpdate](../models/digestupdate.md)] | :heavy_check_mark: | List of updates within this digest section. |
\ No newline at end of file
+| Field | Type | Required | Description |
+| --------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `id` | *str* | :heavy_check_mark: | Unique identifier for the digest section. |
+| `type` | [models.SectionType](../models/sectiontype.md) | :heavy_check_mark: | Type of the section. This defines how the section should be interpreted and rendered in the digest. |
+| `display_name` | *Optional[str]* | :heavy_minus_sign: | Human-readable name for the digest section. |
+| `channel_name` | *Optional[str]* | :heavy_minus_sign: | Name of the channel (applicable for CHANNEL type sections). Used to display in the frontend. |
+| `channel_type` | *Optional[str]* | :heavy_minus_sign: | Channel visibility/type for CHANNEL sections. For Slack this is typically one of
PublicChannel, PrivateChannel. Omit if not applicable or unknown.
|
+| `instance_id` | *Optional[str]* | :heavy_minus_sign: | Instance identifier for the channel or workspace. Used for constructing channel URLs to display in the frontend. |
+| `url` | *Optional[str]* | :heavy_minus_sign: | Optional URL for the digest section. Should be populated only if the section is a CHANNEL type section. |
+| `updates` | List[[models.DigestUpdate](../models/digestupdate.md)] | :heavy_check_mark: | List of updates within this digest section. |
\ No newline at end of file
diff --git a/pyproject.toml b/pyproject.toml
index 8c9d8645..de25fd57 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "glean-api-client"
-version = "0.8.0"
+version = "0.8.1"
description = "Python Client SDK Generated by Speakeasy."
authors = [{ name = "Glean Technologies, Inc." }]
license = "MIT"
diff --git a/src/glean/api_client/_version.py b/src/glean/api_client/_version.py
index 38694bbf..e7e7c156 100644
--- a/src/glean/api_client/_version.py
+++ b/src/glean/api_client/_version.py
@@ -3,10 +3,10 @@
import importlib.metadata
__title__: str = "glean"
-__version__: str = "0.8.0"
+__version__: str = "0.8.1"
__openapi_doc_version__: str = "0.9.0"
-__gen_version__: str = "2.715.0"
-__user_agent__: str = "speakeasy-sdk/python 0.8.0 2.715.0 0.9.0 glean"
+__gen_version__: str = "2.716.3"
+__user_agent__: str = "speakeasy-sdk/python 0.8.1 2.716.3 0.9.0 glean"
try:
if __package__ is not None:
diff --git a/src/glean/api_client/models/digestsection.py b/src/glean/api_client/models/digestsection.py
index 97cdffee..4f31c7af 100644
--- a/src/glean/api_client/models/digestsection.py
+++ b/src/glean/api_client/models/digestsection.py
@@ -20,6 +20,11 @@ class DigestSectionTypedDict(TypedDict):
r"""Human-readable name for the digest section."""
channel_name: NotRequired[str]
r"""Name of the channel (applicable for CHANNEL type sections). Used to display in the frontend."""
+ channel_type: NotRequired[str]
+ r"""Channel visibility/type for CHANNEL sections. For Slack this is typically one of
+ PublicChannel, PrivateChannel. Omit if not applicable or unknown.
+
+ """
instance_id: NotRequired[str]
r"""Instance identifier for the channel or workspace. Used for constructing channel URLs to display in the frontend."""
url: NotRequired[str]
@@ -42,6 +47,12 @@ class DigestSection(BaseModel):
channel_name: Annotated[Optional[str], pydantic.Field(alias="channelName")] = None
r"""Name of the channel (applicable for CHANNEL type sections). Used to display in the frontend."""
+ channel_type: Annotated[Optional[str], pydantic.Field(alias="channelType")] = None
+ r"""Channel visibility/type for CHANNEL sections. For Slack this is typically one of
+ PublicChannel, PrivateChannel. Omit if not applicable or unknown.
+
+ """
+
instance_id: Annotated[Optional[str], pydantic.Field(alias="instanceId")] = None
r"""Instance identifier for the channel or workspace. Used for constructing channel URLs to display in the frontend."""
diff --git a/src/glean/api_client/sdk.py b/src/glean/api_client/sdk.py
index f44a72c7..d8019741 100644
--- a/src/glean/api_client/sdk.py
+++ b/src/glean/api_client/sdk.py
@@ -130,6 +130,7 @@ def __init__(
# pylint: disable=protected-access
self.sdk_configuration.__dict__["_hooks"] = hooks
+
current_server_url, *_ = self.sdk_configuration.get_server_details()
server_url, self.sdk_configuration.client = hooks.sdk_init(
current_server_url, client
diff --git a/src/glean/api_client/utils/annotations.py b/src/glean/api_client/utils/annotations.py
index 387874ed..12e0aa4f 100644
--- a/src/glean/api_client/utils/annotations.py
+++ b/src/glean/api_client/utils/annotations.py
@@ -3,6 +3,7 @@
from enum import Enum
from typing import Any, Optional
+
def get_discriminator(model: Any, fieldname: str, key: str) -> str:
"""
Recursively search for the discriminator attribute in a model.
@@ -25,31 +26,54 @@ def get_field_discriminator(field: Any) -> Optional[str]:
if isinstance(field, dict):
if key in field:
- return f'{field[key]}'
+ return f"{field[key]}"
if hasattr(field, fieldname):
attr = getattr(field, fieldname)
if isinstance(attr, Enum):
- return f'{attr.value}'
- return f'{attr}'
+ return f"{attr.value}"
+ return f"{attr}"
if hasattr(field, upper_fieldname):
attr = getattr(field, upper_fieldname)
if isinstance(attr, Enum):
- return f'{attr.value}'
- return f'{attr}'
+ return f"{attr.value}"
+ return f"{attr}"
return None
+ def search_nested_discriminator(obj: Any) -> Optional[str]:
+ """Recursively search for discriminator in nested structures."""
+ # First try direct field lookup
+ discriminator = get_field_discriminator(obj)
+ if discriminator is not None:
+ return discriminator
+
+ # If it's a dict, search in nested values
+ if isinstance(obj, dict):
+ for value in obj.values():
+ if isinstance(value, list):
+ # Search in list items
+ for item in value:
+ nested_discriminator = search_nested_discriminator(item)
+ if nested_discriminator is not None:
+ return nested_discriminator
+ elif isinstance(value, dict):
+ # Search in nested dict
+ nested_discriminator = search_nested_discriminator(value)
+ if nested_discriminator is not None:
+ return nested_discriminator
+
+ return None
if isinstance(model, list):
for field in model:
- discriminator = get_field_discriminator(field)
+ discriminator = search_nested_discriminator(field)
if discriminator is not None:
return discriminator
- discriminator = get_field_discriminator(model)
+ discriminator = search_nested_discriminator(model)
if discriminator is not None:
return discriminator
- raise ValueError(f'Could not find discriminator field {fieldname} in {model}')
+ raise ValueError(f"Could not find discriminator field {fieldname} in {model}")
diff --git a/tests/mockserver/internal/sdk/models/components/digestsection.go b/tests/mockserver/internal/sdk/models/components/digestsection.go
index da5e9a2f..e316597e 100644
--- a/tests/mockserver/internal/sdk/models/components/digestsection.go
+++ b/tests/mockserver/internal/sdk/models/components/digestsection.go
@@ -11,6 +11,10 @@ type DigestSection struct {
DisplayName *string `json:"displayName,omitempty"`
// Name of the channel (applicable for CHANNEL type sections). Used to display in the frontend.
ChannelName *string `json:"channelName,omitempty"`
+ // Channel visibility/type for CHANNEL sections. For Slack this is typically one of
+ // PublicChannel, PrivateChannel. Omit if not applicable or unknown.
+ //
+ ChannelType *string `json:"channelType,omitempty"`
// Instance identifier for the channel or workspace. Used for constructing channel URLs to display in the frontend.
InstanceID *string `json:"instanceId,omitempty"`
// Optional URL for the digest section. Should be populated only if the section is a CHANNEL type section.
@@ -47,6 +51,13 @@ func (o *DigestSection) GetChannelName() *string {
return o.ChannelName
}
+func (o *DigestSection) GetChannelType() *string {
+ if o == nil {
+ return nil
+ }
+ return o.ChannelType
+}
+
func (o *DigestSection) GetInstanceID() *string {
if o == nil {
return nil
diff --git a/tests/test_agents.py b/tests/test_agents.py
index b5bc99a7..1d18b766 100644
--- a/tests/test_agents.py
+++ b/tests/test_agents.py
@@ -63,7 +63,7 @@ def test_agents_search_agents():
@pytest.mark.skip(
- reason="incomplete test found please make sure to address the following errors: [`workflow step createAndStreamRun.test referencing operation createAndStreamRun is not currently supported`]"
+ reason="incomplete test found please make sure to address the following errors: [`workflow step createAndStreamRun.test referencing operation createAndStreamRun is missing required request body`]"
)
def test_agents_create_and_stream_run():
pass