Skip to content

feat(streams): Streams API#2534

Merged
andersfylling merged 22 commits into
masterfrom
andersfylling/cognite-sdk/streams-api
May 7, 2026
Merged

feat(streams): Streams API#2534
andersfylling merged 22 commits into
masterfrom
andersfylling/cognite-sdk/streams-api

Conversation

@andersfylling
Copy link
Copy Markdown
Contributor

@andersfylling andersfylling commented Mar 25, 2026

Summary

Add streams api to sdk.

Example

from cognite.client import CogniteClient
from cognite.client.data_classes.data_modeling.streams import StreamDeleteItem, StreamWrite

client = CogniteClient(...)  # your usual ClientConfig / credentials

external_id = "my_stream"
client.data_modeling.streams.create([StreamWrite(external_id, {"template": {"name": "ImmutableTestStream"}})])
client.data_modeling.streams.list()
client.data_modeling.streams.retrieve(external_id)
client.data_modeling.streams.delete([StreamDeleteItem(external_id)])

This PR does not add the Records API (#2535).

closes #2519
closes #2246

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 26, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.02%. Comparing base (03ba6fa) to head (11ce01c).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2534      +/-   ##
==========================================
+ Coverage   92.99%   93.02%   +0.02%     
==========================================
  Files         482      486       +4     
  Lines       48995    49208     +213     
==========================================
+ Hits        45564    45775     +211     
- Misses       3431     3433       +2     
Files with missing lines Coverage Δ
cognite/client/_api/data_modeling/__init__.py 100.00% <100.00%> (ø)
cognite/client/_api/data_modeling/streams.py 100.00% <100.00%> (ø)
cognite/client/_cognite_client.py 96.49% <100.00%> (+0.03%) ⬆️
cognite/client/_sync_api/data_modeling/__init__.py 100.00% <100.00%> (ø)
cognite/client/_sync_api/data_modeling/streams.py 100.00% <100.00%> (ø)
...nite/client/data_classes/data_modeling/__init__.py 100.00% <100.00%> (ø)
...gnite/client/data_classes/data_modeling/streams.py 100.00% <100.00%> (ø)
cognite/client/testing.py 100.00% <100.00%> (ø)
cognite/client/utils/_url.py 100.00% <ø> (ø)
...s_unit/test_api/test_data_modeling/test_streams.py 100.00% <100.00%> (ø)
... and 2 more

... and 4 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@andersfylling andersfylling marked this pull request as ready for review March 26, 2026 14:56
@andersfylling andersfylling requested review from a team as code owners March 26, 2026 14:57
@gemini-code-assist

This comment was marked as outdated.

gemini-code-assist[bot]

This comment was marked as outdated.

@andersfylling andersfylling changed the base branch from master to pysdk-release-v8 March 26, 2026 15:15
@andersfylling andersfylling force-pushed the andersfylling/cognite-sdk/streams-api branch from c0ac1ca to b83f313 Compare March 26, 2026 15:15
@andersfylling

This comment was marked as resolved.

gemini-code-assist[bot]

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor

@haakonvt haakonvt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Part 1 of review: cognite/client/_api/streams/__init__.py

Comment thread cognite/client/_api/streams/__init__.py Outdated
Comment thread cognite/client/_api/streams/__init__.py Outdated
Comment thread cognite/client/_api/streams/__init__.py Outdated
Comment thread cognite/client/_api/streams/__init__.py Outdated
Comment thread cognite/client/_api/streams/__init__.py Outdated
Comment thread cognite/client/_api/streams/__init__.py Outdated
Comment thread cognite/client/_api/streams/__init__.py Outdated
Comment thread cognite/client/_api/streams/__init__.py Outdated
Comment thread cognite/client/_api/streams/__init__.py Outdated
Comment thread cognite/client/_api/streams/__init__.py Outdated
@andersfylling andersfylling changed the base branch from pysdk-release-v8 to master March 30, 2026 12:52
@andersfylling andersfylling force-pushed the andersfylling/cognite-sdk/streams-api branch from 1902069 to 02d53d4 Compare March 30, 2026 13:34
@evertoncolling

This comment was marked as resolved.

@andersfylling andersfylling changed the title feat(streams): ILA Streams API feat(streams): Streams API Apr 14, 2026
@andersfylling andersfylling force-pushed the andersfylling/cognite-sdk/streams-api branch from 29a0184 to 6829245 Compare April 14, 2026 11:28
@andersfylling andersfylling force-pushed the andersfylling/cognite-sdk/streams-api branch from c2d5bad to 3225b62 Compare April 14, 2026 13:32
andersfylling and others added 9 commits April 14, 2026 15:44
The StreamsAPI needs to chunk items one at a time for create and delete
operations, similar to other APIs like AgentsAPI. This ensures each stream
is processed in a separate API request rather than being bundled together.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Remove unused imports that were causing lint failures (F401 errors):
- asyncio, Coroutine, Iterator (not used)
- Any, Literal, overload, TYPE_CHECKING (not used)
- APIClient (not used)
- SyncIterator, run_sync (not used)
- _get_event_loop_executor (not used)
- pandas, ClientConfig (not used)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
andersfylling added a commit that referenced this pull request Apr 20, 2026
… PR 2534 structure

This refactors the Streams and Records API to be part of the data_modeling module
rather than a separate top-level streams module, matching the structure of PR #2534.

Changes:
- Move StreamsAPI from _api/streams to _api/data_modeling/streams
- Move StreamsRecordsAPI from _api/streams/records to _api/data_modeling/records
- Move stream data classes to data_modeling/streams.py (includes record classes)
- Integrate records API into StreamsAPI via self.records attribute
- Remove direct self.streams attribute from AsyncCogniteClient
- Streams now accessed via client.data_modeling.streams
- Generate sync API wrappers for new locations
- Update all imports and exports

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Comment thread cognite/client/data_classes/data_modeling/streams.py Outdated
Comment thread cognite/client/data_classes/data_modeling/streams.py Outdated
Comment thread cognite/client/data_classes/data_modeling/streams.py
Comment thread cognite/client/data_classes/data_modeling/streams.py Outdated
Comment thread tests/tests_unit/test_api/test_data_modeling/test_streams.py
Comment thread tests/tests_unit/test_data_classes/test_data_models/test_streams.py Outdated
Comment thread cognite/client/_api/data_modeling/streams.py
Comment thread cognite/client/_api/data_modeling/streams.py
Comment thread cognite/client/_api/data_modeling/streams.py Outdated
Comment thread cognite/client/_api/data_modeling/streams.py Outdated
Copy link
Copy Markdown
Contributor

@haakonvt haakonvt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 more comments, but looking great 🤩

Comment on lines +63 to +64
res = await self._get(url_path=self._RESOURCE_PATH, semaphore=self._get_semaphore("read"))
return StreamList._load(res.json()["items"])
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that should be fine:

return await self._list("GET", list_cls=StreamList, resource_cls=Stream)


@classmethod
def _parse_settings(cls, raw: dict[str, Any]) -> StreamTemplateWriteSettings | dict[str, Any]:
if set(raw.keys()) == {"template"} and isinstance(raw["template"], dict) and "name" in raw["template"]:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the presence of other keys besides "template" prevent this from triggering? If no, then consider structural pattern matching also:

match raw:
    case {"template": {"name": str()}}:
        return StreamTemplateWriteSettings._load(raw)
    case _:
        return raw

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this is currently required. and going forward we want users to be cognizant on what template is configured as it directly impacts their usecase. So for now I think this is fine.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me!

dug into our code, future plans, etc. I don't see a reason to support this and I think this came about from AI slop. my fault :sadpanda:
manually verified that extra uri args are ignored for the endpoint. eg. limit parameter that is injected by default
haakonvt
haakonvt previously approved these changes May 7, 2026
since we now use _list we need to update the regex to allow injected uri args like limit
Copy link
Copy Markdown
Contributor

@haakonvt haakonvt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦄

@haakonvt haakonvt added risk-review-ongoing Risk review is in progress waiting-for-team Waiting for the submitter or reviewer of the PR to take an action labels May 7, 2026
@haakonvt haakonvt self-assigned this May 7, 2026
@andersfylling andersfylling added this pull request to the merge queue May 7, 2026
Merged via the queue into master with commit 1979253 May 7, 2026
62 of 66 checks passed
@andersfylling andersfylling deleted the andersfylling/cognite-sdk/streams-api branch May 7, 2026 16:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk-review-ongoing Risk review is in progress waiting-for-team Waiting for the submitter or reviewer of the PR to take an action

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants