Skip to content

Conversation

@audunska
Copy link
Contributor

@audunska audunska commented Oct 27, 2025

The Container class already had a ContainerApply write version, but the member classes didn't. Since we added state fields, the read and write versions now differ, so split them.

Also converted them to dataclasses.

@haakonvt feel free to ignore this PR until you've gotten the alpha version out :)

@audunska audunska requested review from a team as code owners October 27, 2025 09:27
@gemini-code-assist
Copy link
Contributor

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

@audunska audunska changed the base branch from master to v8-change-requests-to-httpx October 27, 2025 09:28
@audunska audunska changed the title refactor!(v8): Split container classes into read/write versions (DM-3215) refactor! [V8]: Split container classes into read/write versions (DM-3215) Oct 27, 2025
@audunska audunska changed the title refactor! [V8]: Split container classes into read/write versions (DM-3215) refactor!: [V8] Split container classes into read/write versions (DM-3215) Oct 27, 2025
@audunska audunska force-pushed the v8-split-container-read-write branch from 1c7537d to 1a7da07 Compare October 27, 2025 09:30
@audunska
Copy link
Contributor Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request is a significant and well-executed refactoring of the container-related data classes. The introduction of dataclasses and the separation of read and write models (Container vs. ContainerApply) greatly improve code clarity, type safety, and maintainability, aligning well with the repository's style guide. The use of ...Core base classes to abstract common functionality is an excellent pattern.

However, I've identified a critical issue in the new implementation. The state field in the read versions of Constraint and Index classes has been changed from optional to required. This could lead to KeyError exceptions if the API omits this field in its responses, which the previous implementation handled gracefully. I've provided detailed comments and suggestions to address this potential regression.

haakonvt and others added 21 commits October 27, 2025 20:10
- fix tests/tests_unit/test_api/test_assets.py
- fix tests/tests_unit/test_api/test_data_modeling/test_containers.py
- fix tests/tests_unit/test_api/test_data_sets.py
- fix tests/tests_unit/test_api/test_datapoints.py
- fix tests/tests_unit/test_api/test_documents.py
- fix tests/tests_unit/test_api/test_entity_matching.py
- fix tests/tests_unit/test_api/test_events.py
- fix tests/tests_unit/test_api/test_extractionpipelines.py
- fix tests/tests_unit/test_api/test_files.py (puh!)
- fix tests/tests_unit/test_api/test_functions.py (mega puuh)
- fix tests/tests_unit/test_api/test_iam.py
- fix tests/tests_unit/test_api/test_labels.py
- fix tests/tests_unit/test_api/test_raw.py
- fix tests/tests_unit/test_api/test_relationships.py
- fix tests/tests_unit/test_api/test_sequences.py (puh again)
- fix tests/tests_unit/test_api/test_synthetic_time_series.py
- fix tests/tests_unit/test_api/test_time_series.py
- fix tests/tests_unit/test_api/test_vision_extract.py
- fix tests/tests_unit/test_api_client.py ( 👀 )
- fix tests/tests_unit/test_cognite_client.py
- fix tests/tests_unit/test_data_classes/test_capabilities.py
- fix tests/tests_unit/test_http_client.py
- fix tests/tests_unit/test_meta.py
@haakonvt haakonvt force-pushed the v8-change-requests-to-httpx branch 2 times, most recently from e92c87f to 6a22e7e Compare October 28, 2025 11:57
@haakonvt haakonvt force-pushed the v8-change-requests-to-httpx branch from 3f22dcd to 016505a Compare October 28, 2025 20:13
@haakonvt haakonvt force-pushed the v8-split-container-read-write branch from 1a7da07 to 0b8f877 Compare October 28, 2025 20:14
Copy link
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.

Thanks for having the patience to get all these classes split into proper read and write versions 😄 The removal of object.__setattr__ also brings joy to my heart!

A few questions:

return self.as_id().as_property_ref(property)


@dataclass(frozen=True)
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm unsure about frozen on write classes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wanted to remove frozen, but you're not allowed to inherit frozen classes from non-frozen classes and vice versa. So they all need to be frozen or not.

Copy link
Contributor

Choose a reason for hiding this comment

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

Huh, I see. That makes me a bit sad 🥲 Thoughts @erlendvollset ?

Comment on lines +126 to +128
property_loader=ContainerPropertyApply._load,
constraint_loader=ConstraintApply._load,
index_loader=IndexApply._load,
Copy link
Contributor

Choose a reason for hiding this comment

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

We seem to be always calling ._load on the passed callables - then I think I would prefer to pass the classes instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The problem was with the Constraint and Index classes. If we switch the argument to constraint_class: type[ConstraintCore] and pass constraint_class=Constraint or constraint_class=ConstraintApply, mypy will complain with

cognite/client/data_classes/data_modeling/containers.py:127: error: Only concrete class can be given where "type[ConstraintCore]" is expected  [type-abstract]

So I switched to using loader functions for these arguments.

We can still pass classes for the property. Should we?

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh how I love mypy 🙃 Does it work with a TypeVar using bound?

Anyway, feel free to just leave it as is 👍

Comment on lines 158 to 161
is_global: bool = False
last_updated_time: int = 0
created_time: int = 0
used_for: Literal["node", "edge", "all"] = "all"
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do these have default values?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. They shouldn't.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@haakonvt I removed all defaults from the read classes and made them kw_only. We don't care about these being convenient to construct.

The write classes can have defaults, but I wonder if we might want to make them kw_only too?

Copy link
Contributor

Choose a reason for hiding this comment

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

Nice, agree on the read classes 👍

I think we shouldn't force the user into a specific way to instantiate the write classes.

Comment on lines +286 to +287
nullable=resource.get("nullable", True),
auto_increment=resource.get("autoIncrement", False),
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you elaborate a bit on the change away from the previous behaviour? (Wrt # If nothing is specified, we will pass through null values)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe not a very conscious decision. I just found it cleaner to use sensible defaults where appropriate. But maybe we should keep them as optional and retain the None pass-through. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

Having thought some more about it, I think your changes make sense.

Would like to know the reason for the previous behaviour choice though

and make them `kw_only`
@haakonvt haakonvt force-pushed the v8-change-requests-to-httpx branch 10 times, most recently from c605eee to 1ba5b84 Compare November 10, 2025 13:27
@haakonvt
Copy link
Contributor

Merged into #2387 , closing

@haakonvt haakonvt closed this Nov 12, 2025
@haakonvt haakonvt deleted the v8-split-container-read-write branch November 12, 2025 09:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants