contentgrid-application-client 0.2.9__tar.gz → 0.2.11__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. {contentgrid_application_client-0.2.9/src/contentgrid_application_client.egg-info → contentgrid_application_client-0.2.11}/PKG-INFO +4 -2
  2. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/pyproject.toml +6 -2
  3. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/src/contentgrid_application_client/application.py +54 -40
  4. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11/src/contentgrid_application_client.egg-info}/PKG-INFO +4 -2
  5. contentgrid_application_client-0.2.11/src/contentgrid_application_client.egg-info/requires.txt +1 -0
  6. contentgrid_application_client-0.2.11/src/contentgrid_application_client.egg-info/scm_version.json +8 -0
  7. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/tests/test_profile.py +34 -34
  8. contentgrid_application_client-0.2.9/src/contentgrid_application_client.egg-info/requires.txt +0 -1
  9. contentgrid_application_client-0.2.9/src/contentgrid_application_client.egg-info/scm_version.json +0 -8
  10. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/LICENSE +0 -0
  11. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/README.md +0 -0
  12. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/pytest.ini +0 -0
  13. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/requirements.txt +0 -0
  14. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/setup.cfg +0 -0
  15. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/setup.py +0 -0
  16. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/src/contentgrid_application_client/__init__.py +0 -0
  17. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/src/contentgrid_application_client/py.typed +0 -0
  18. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/src/contentgrid_application_client.egg-info/SOURCES.txt +0 -0
  19. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/src/contentgrid_application_client.egg-info/dependency_links.txt +0 -0
  20. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/src/contentgrid_application_client.egg-info/scm_file_list.json +0 -0
  21. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/src/contentgrid_application_client.egg-info/top_level.txt +0 -0
  22. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/tests/example-docs/document.jpg +0 -0
  23. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/tests/example-docs/resume.pdf +0 -0
  24. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/tests/fixtures.py +0 -0
  25. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/tests/test_collection.py +0 -0
  26. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/tests/test_content.py +0 -0
  27. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/tests/test_curies.py +0 -0
  28. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/tests/test_entity_creation.py +0 -0
  29. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/tests/test_hal_form_type_check.py +0 -0
  30. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/tests/test_openapi.py +0 -0
  31. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/tests/test_prompting.py +0 -0
  32. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/tests/test_relations.py +0 -0
  33. {contentgrid_application_client-0.2.9 → contentgrid_application_client-0.2.11}/tests/test_search.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: contentgrid-application-client
3
- Version: 0.2.9
3
+ Version: 0.2.11
4
4
  Summary: Python Client for interacting with ContentGrid Applications
5
5
  Author-email: Ranec Belpaire <ranec.belpaire@xenit.eu>
6
6
  License: Copyright 2024 Xenit Solutions
@@ -16,13 +16,15 @@ License: Copyright 2024 Xenit Solutions
16
16
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
17
  See the License for the specific language governing permissions and
18
18
  limitations under the License.
19
+ Project-URL: Homepage, https://github.com/xenit-eu/contentgrid-python-client
20
+ Project-URL: Source, https://github.com/xenit-eu/contentgrid-python-client
19
21
  Classifier: Development Status :: 4 - Beta
20
22
  Classifier: Operating System :: OS Independent
21
23
  Classifier: Programming Language :: Python :: 3
22
24
  Requires-Python: >=3.5
23
25
  Description-Content-Type: text/markdown
24
26
  License-File: LICENSE
25
- Requires-Dist: contentgrid-hal-client==0.2.9
27
+ Requires-Dist: contentgrid-hal-client==0.2.11
26
28
  Dynamic: license-file
27
29
  Dynamic: requires-dist
28
30
 
@@ -9,7 +9,7 @@ description = "Python Client for interacting with ContentGrid Applications"
9
9
  readme = "README.md"
10
10
  authors = [{ name = "Ranec Belpaire", email = "ranec.belpaire@xenit.eu" }]
11
11
  license = { file = "LICENSE" }
12
-
12
+
13
13
  classifiers = [
14
14
  "Development Status :: 4 - Beta",
15
15
  "Operating System :: OS Independent",
@@ -18,6 +18,10 @@ classifiers = [
18
18
 
19
19
  requires-python = ">=3.5"
20
20
 
21
+ [project.urls]
22
+ Homepage = "https://github.com/xenit-eu/contentgrid-python-client"
23
+ Source = "https://github.com/xenit-eu/contentgrid-python-client"
24
+
21
25
  [tool.setuptools_scm]
22
- write_to = "_version.txt"
26
+ write_to = "_version.txt"
23
27
  root = "../"
@@ -25,6 +25,7 @@ hal_form_type_check = {
25
25
  }
26
26
 
27
27
  DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ"
28
+ MULTI_VALUED_ATTRIBUTE_TYPES = ["string_set"]
28
29
 
29
30
 
30
31
  def is_valid_date_format(date_string):
@@ -59,6 +60,7 @@ class InteractiveApplicationResponse(InteractiveHALResponse):
59
60
  class SearchType(Enum):
60
61
  EXACT_MATCH = "exact-match"
61
62
  PREFIX_MATCH = "prefix-match"
63
+ CONTAINS = "contains"
62
64
  FULL_TEXT_MATCH = "full-text"
63
65
  LESS_THAN = "less-than"
64
66
  LESS_THAN_OR_EQUAL = "less-than-or-equal"
@@ -258,11 +260,11 @@ class EntityObject(InteractiveApplicationResponse):
258
260
  params = self.client._add_page_and_size_to_params(size=size, params=params)
259
261
  relation_link = self.get_relation_link(relation_name=relation_name)
260
262
  return self.client.follow_link(relation_link, infer_type=EntityCollection, params=params)
261
-
263
+
262
264
  def get_related_entity(self, relation_name: str) -> "EntityObject":
263
265
  relation_link = self.get_relation_link(relation_name=relation_name)
264
266
  return self.client.follow_link(relation_link, infer_type=EntityObject)
265
-
267
+
266
268
  def set_related_entity(self, relation_name: str, related_entity : "EntityObject") -> None:
267
269
  self.put_relation(relation_name=relation_name, related_entity_links=[related_entity], prefix_client_endpoint=True)
268
270
 
@@ -481,6 +483,7 @@ class AttributeProfile(InteractiveApplicationResponse):
481
483
  self.__prefix_search_option: Optional[SearchOption] = None
482
484
  self.__exact_search_option: Optional[SearchOption] = None
483
485
  self.__full_text_search_option: Optional[SearchOption] = None
486
+ self.__contains_search_option: Optional[SearchOption] = None
484
487
  self.__less_than_search_option: Optional[SearchOption] = None
485
488
  self.__less_than_or_equal_search_option: Optional[SearchOption] = None
486
489
  self.__greater_than_search_option: Optional[SearchOption] = None
@@ -489,9 +492,21 @@ class AttributeProfile(InteractiveApplicationResponse):
489
492
  def get_nested_attributes(self) -> List["AttributeProfile"]:
490
493
  return self.nested_attributes
491
494
 
495
+ @property
492
496
  def is_content_attribute(self) -> bool:
493
497
  return self.type == "object" and any(attr.name in ["length", "mimetype", "filename"] for attr in self.nested_attributes)
494
498
 
499
+ @property
500
+ def is_audit_attribute(self) -> bool:
501
+ return self.has_created_by_constraint() or \
502
+ self.has_created_date_constraint() or \
503
+ self.has_modified_by_constraint() or \
504
+ self.has_modified_date_constraint()
505
+
506
+ @property
507
+ def is_multi_valued_attribute(self) -> bool:
508
+ return self.type in MULTI_VALUED_ATTRIBUTE_TYPES
509
+
495
510
  def get_constraints(self) -> List[AttributeConstraint]:
496
511
  return self.constraints
497
512
 
@@ -506,32 +521,25 @@ class AttributeProfile(InteractiveApplicationResponse):
506
521
 
507
522
  def has_constrained_values(self) -> bool:
508
523
  return self.get_constraint("allowed-values") is not None
509
-
524
+
510
525
  def has_allowed_values_constraint(self) -> bool:
511
526
  return self.has_constrained_values()
512
-
527
+
513
528
  def has_unique_constraint(self) -> bool:
514
529
  return self.get_constraint("unique") is not None
515
-
530
+
516
531
  def has_created_by_constraint(self) -> bool:
517
532
  return self.get_constraint("created-by") is not None
518
-
533
+
519
534
  def has_created_date_constraint(self) -> bool:
520
535
  return self.get_constraint("created-date") is not None
521
-
536
+
522
537
  def has_modified_by_constraint(self) -> bool:
523
538
  return self.get_constraint("modified-by") is not None
524
-
539
+
525
540
  def has_modified_date_constraint(self) -> bool:
526
541
  return self.get_constraint("modified-date") is not None
527
-
528
- @property
529
- def is_audit_attribute(self) -> bool:
530
- return self.has_created_by_constraint() or \
531
- self.has_created_date_constraint() or \
532
- self.has_modified_by_constraint() or \
533
- self.has_modified_date_constraint()
534
-
542
+
535
543
  def get_allowed_values(self) -> Optional[List[str]]:
536
544
  if self.has_constrained_values():
537
545
  return self.get_constraint("allowed-values").values # type: ignore
@@ -557,7 +565,7 @@ class AttributeProfile(InteractiveApplicationResponse):
557
565
  if self.__prefix_search_option is None:
558
566
  self.__prefix_search_option = self.get_search_option(search_type=SearchType.PREFIX_MATCH)
559
567
  return self.__prefix_search_option
560
-
568
+
561
569
  @property
562
570
  def _full_text_search_option(self) -> Optional[SearchOption]:
563
571
  if self.__full_text_search_option is None:
@@ -575,6 +583,12 @@ class AttributeProfile(InteractiveApplicationResponse):
575
583
  self.__exact_search_option = case_insensitive_match
576
584
  return self.__exact_search_option
577
585
 
586
+ @property
587
+ def _contains_search_option(self) -> Optional[SearchOption]:
588
+ if self.__contains_search_option is None:
589
+ self.__contains_search_option = self.get_search_option(search_type=SearchType.CONTAINS)
590
+ return self.__contains_search_option
591
+
578
592
  @property
579
593
  def _less_than_search_option(self) -> Optional[SearchOption]:
580
594
  if self.__less_than_search_option is None:
@@ -710,18 +724,18 @@ _search_form_relation_delimiter = "."
710
724
 
711
725
  class AttributeSearch(ABC):
712
726
  """Abstract base class for attribute search implementations."""
713
-
727
+
714
728
  def __init__(self, attribute_name: str, ignore_errors: bool = False) -> None:
715
729
  self.attribute_name: str = attribute_name
716
730
  self.ignore_errors: bool = ignore_errors
717
-
731
+
718
732
  @abstractmethod
719
733
  def get_search_params(self, attribute_profile: AttributeProfile) -> List[SearchParam]:
720
734
  """Convert this search specification into search parameters.
721
-
735
+
722
736
  Args:
723
737
  attribute_profile: The attribute profile to validate against and extract search options from.
724
-
738
+
725
739
  Returns:
726
740
  List of SearchParam objects representing the search criteria.
727
741
  """
@@ -730,11 +744,11 @@ class AttributeSearch(ABC):
730
744
 
731
745
  class AttributeMatchSearch(AttributeSearch):
732
746
  def __init__(
733
- self,
734
- attribute_name: str,
735
- value: Union[float | int | date | datetime | bool | str],
736
- use_prefix: bool = False,
737
- use_full_text: bool = False,
747
+ self,
748
+ attribute_name: str,
749
+ value: Union[float | int | date | datetime | bool | str],
750
+ use_prefix: bool = False,
751
+ use_full_text: bool = False,
738
752
  use_exact: bool = False,
739
753
  ignore_errors: bool = False
740
754
  ) -> None:
@@ -753,7 +767,7 @@ class AttributeMatchSearch(AttributeSearch):
753
767
  or (not attribute_profile._exact_search_option
754
768
  and not attribute_profile._prefix_search_option
755
769
  and not attribute_profile._full_text_search_option)
756
- ):
770
+ ):
757
771
  raise BadRequest(f"Attribute {self.attribute_name} does not support search. Available options: {attribute_profile.search_options}")
758
772
 
759
773
  # Extract available search options
@@ -762,10 +776,10 @@ class AttributeMatchSearch(AttributeSearch):
762
776
  exact_option = attribute_profile._exact_search_option
763
777
 
764
778
  selected_option = None
765
-
779
+
766
780
  # Check if any specific search type is explicitly requested
767
781
  any_use_flag_set = self.use_prefix or self.use_full_text or self.use_exact
768
-
782
+
769
783
  if any_use_flag_set:
770
784
  # Use explicitly requested search types (in priority order)
771
785
  if self.use_full_text and full_text_option:
@@ -788,7 +802,7 @@ class AttributeMatchSearch(AttributeSearch):
788
802
  selected_option = exact_option
789
803
  elif attribute_profile.has_search_capability():
790
804
  selected_option = attribute_profile.search_options[0]
791
-
805
+
792
806
  if selected_option:
793
807
  search_params.append(SearchParam(value=self.value, option=selected_option))
794
808
 
@@ -943,12 +957,12 @@ class ContentGridApplicationClient(HALFormsClient):
943
957
  self.attribute_validation = attribute_validation
944
958
  self.use_profile_cache = use_profile_cache
945
959
  self.profile_cache: dict[str, dict[str, Any]] = {}
946
-
960
+
947
961
  # PROFILE CACHING
948
962
  def load_profile_cache(self, url: str, json_data: dict | str) -> None:
949
963
  """
950
964
  Load JSON data into the profile cache.
951
-
965
+
952
966
  Args:
953
967
  url: The URL to cache the response for (relative to client_endpoint)
954
968
  json_data: The JSON data to cache (as dict or JSON string)
@@ -958,11 +972,11 @@ class ContentGridApplicationClient(HALFormsClient):
958
972
 
959
973
  self.profile_cache[url] = cast(dict, json_data)
960
974
  logging.info(f"Loaded JSON data into profile cache for {url}")
961
-
975
+
962
976
  def clear_profile_cache(self):
963
977
  logging.info(f"Clearing profile cache... clearing {len(self.profile_cache.keys())} entries")
964
- self.profile_cache = {}
965
-
978
+ self.profile_cache = {}
979
+
966
980
  def get_profile(self) -> Profile:
967
981
  if self.use_profile_cache:
968
982
  profile_cache_key = self.client_endpoint.click("/profile").normalize().to_text()
@@ -982,7 +996,7 @@ class ContentGridApplicationClient(HALFormsClient):
982
996
 
983
997
  def get_entity_profiles(self) -> List[EntityProfile]:
984
998
  return [entity_profile for entity_profile in self.get_profile().get_entity_profiles_generator()]
985
-
999
+
986
1000
  def load_or_fetch_entity_profile(self, profile_link : HALLink, params: dict={}) -> EntityProfile:
987
1001
  if self.use_profile_cache:
988
1002
  if profile_link.uri in self.profile_cache:
@@ -1158,12 +1172,12 @@ class ContentGridApplicationClient(HALFormsClient):
1158
1172
 
1159
1173
  def _prefix_url_in_form_payload(self, template: HALFormsTemplate, payload: dict) -> None:
1160
1174
  """Prefix URL properties in the payload with the client_endpoint if needed.
1161
-
1162
- Modifies the payload in-place, prefixing any URL-type properties with the
1175
+
1176
+ Modifies the payload in-place, prefixing any URL-type properties with the
1163
1177
  client_endpoint if they don't already start with it.
1164
1178
  """
1165
1179
  client_endpoint = self.client_endpoint
1166
-
1180
+
1167
1181
  for key, value in payload.items():
1168
1182
  try:
1169
1183
  hal_property = None
@@ -1171,7 +1185,7 @@ class ContentGridApplicationClient(HALFormsClient):
1171
1185
  if prop.name == key:
1172
1186
  hal_property = prop
1173
1187
  break
1174
-
1188
+
1175
1189
  if hal_property and hal_property.type == HALFormsPropertyType.url:
1176
1190
  if isinstance(value, list):
1177
1191
  payload[key] = [
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: contentgrid-application-client
3
- Version: 0.2.9
3
+ Version: 0.2.11
4
4
  Summary: Python Client for interacting with ContentGrid Applications
5
5
  Author-email: Ranec Belpaire <ranec.belpaire@xenit.eu>
6
6
  License: Copyright 2024 Xenit Solutions
@@ -16,13 +16,15 @@ License: Copyright 2024 Xenit Solutions
16
16
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
17
  See the License for the specific language governing permissions and
18
18
  limitations under the License.
19
+ Project-URL: Homepage, https://github.com/xenit-eu/contentgrid-python-client
20
+ Project-URL: Source, https://github.com/xenit-eu/contentgrid-python-client
19
21
  Classifier: Development Status :: 4 - Beta
20
22
  Classifier: Operating System :: OS Independent
21
23
  Classifier: Programming Language :: Python :: 3
22
24
  Requires-Python: >=3.5
23
25
  Description-Content-Type: text/markdown
24
26
  License-File: LICENSE
25
- Requires-Dist: contentgrid-hal-client==0.2.9
27
+ Requires-Dist: contentgrid-hal-client==0.2.11
26
28
  Dynamic: license-file
27
29
  Dynamic: requires-dist
28
30
 
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "0.2.11",
3
+ "distance": 0,
4
+ "node": "g09d57a7729482291739655ce81dd3657f494faf3",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-10-02"
8
+ }
@@ -61,7 +61,7 @@ def test_content_attribute_detection(cg_client: ContentGridApplicationClient):
61
61
  entity_profile = cg_client.get_entity_profile(profile.get_entity_links()[0].name)
62
62
 
63
63
  for attribute in entity_profile.get_attribute_profiles():
64
- if attribute.is_content_attribute():
64
+ if attribute.is_content_attribute:
65
65
  nested_attrs = attribute.get_nested_attributes()
66
66
  assert any(attr.name in ["length", "mimetype", "filename"] for attr in nested_attrs)
67
67
 
@@ -111,9 +111,9 @@ def test_load_profile_cache_with_dict(cg_client: ContentGridApplicationClient):
111
111
  "name": "test-entity",
112
112
  "description": "Test entity"
113
113
  }
114
-
114
+
115
115
  cg_client.load_profile_cache("/profile/test-entity", test_data)
116
-
116
+
117
117
  # Verify it's in the cache
118
118
  assert "/profile/test-entity" in cg_client.profile_cache
119
119
  cached_data = cg_client.profile_cache["/profile/test-entity"]
@@ -129,9 +129,9 @@ def test_load_profile_cache_with_json_string(cg_client: ContentGridApplicationCl
129
129
  "name": "test-entity2"
130
130
  }
131
131
  json_string = json.dumps(test_data)
132
-
132
+
133
133
  cg_client.load_profile_cache("/profile/test-entity2", json_string)
134
-
134
+
135
135
  # Verify it's in the cache
136
136
  assert "/profile/test-entity2" in cg_client.profile_cache
137
137
  cached_data = cg_client.profile_cache["/profile/test-entity2"]
@@ -142,65 +142,65 @@ def test_profile_cache_hit_returns_cached_response(cg_client: ContentGridApplica
142
142
  # First request to populate cache
143
143
  profile1 = cg_client.get_profile()
144
144
  initial_cache_size = len(cg_client.profile_cache)
145
-
145
+
146
146
  # Second request should use cache
147
147
  profile2 = cg_client.get_profile()
148
-
148
+
149
149
  # Cache size should not have increased
150
150
  assert len(cg_client.profile_cache) == initial_cache_size
151
-
151
+
152
152
  # Both profiles should have the same data
153
153
  assert profile1.data == profile2.data
154
154
 
155
155
  def test_profile_cache_only_affects_profile_endpoints(cg_client: ContentGridApplicationClient):
156
156
  """Test that cache only affects profile endpoints"""
157
157
  initial_cache_size = len(cg_client.profile_cache)
158
-
158
+
159
159
  # Get profile - should be cached
160
160
  cg_client.get_profile()
161
-
161
+
162
162
  # Cache should have grown
163
163
  assert len(cg_client.profile_cache) > initial_cache_size
164
-
164
+
165
165
  # Getting entity collection should not add to profile cache
166
166
  profile = cg_client.get_profile()
167
167
  if profile.get_entity_links():
168
168
  entity_name = profile.get_entity_links()[0].name
169
169
  entity_profile = cg_client.get_entity_profile(entity_name)
170
170
  cache_size_after_entity_profile = len(cg_client.profile_cache)
171
-
171
+
172
172
  # Getting the entity collection should not be cached
173
173
  try:
174
174
  cg_client.get_entity_collection(entity_name, size=1)
175
175
  except Exception:
176
176
  pass # We don't care if this fails, just testing cache behavior
177
-
177
+
178
178
  # Profile cache size should not change from non-profile requests
179
179
  assert len(cg_client.profile_cache) >= cache_size_after_entity_profile
180
180
 
181
181
  def test_profile_cache_caches_entity_profiles(cg_client: ContentGridApplicationClient):
182
182
  """Test that entity profile requests are also cached"""
183
183
  profile = cg_client.get_profile()
184
-
184
+
185
185
  if not profile.get_entity_links():
186
186
  pytest.skip("No entity profiles available to test caching")
187
-
187
+
188
188
  entity_name = profile.get_entity_links()[0].name
189
189
  initial_cache_size = len(cg_client.profile_cache)
190
-
190
+
191
191
  # First request
192
192
  entity_profile1 = cg_client.get_entity_profile(entity_name)
193
193
  cache_size_after_first = len(cg_client.profile_cache)
194
-
194
+
195
195
  # Cache should have grown (at least entity profile URL)
196
196
  assert cache_size_after_first > initial_cache_size
197
-
197
+
198
198
  # Second request - should hit cache
199
199
  entity_profile2 = cg_client.get_entity_profile(entity_name)
200
-
200
+
201
201
  # Cache size should not change
202
202
  assert len(cg_client.profile_cache) == cache_size_after_first
203
-
203
+
204
204
  # Data should be the same
205
205
  assert entity_profile1.name == entity_profile2.name
206
206
 
@@ -208,7 +208,7 @@ def test_clear_empty_profile_cache(cg_client: ContentGridApplicationClient):
208
208
  """Test clearing an empty cache doesn't cause issues"""
209
209
  # Clear empty cache
210
210
  cg_client.clear_profile_cache()
211
-
211
+
212
212
  # Verify cache is still empty
213
213
  assert len(cg_client.profile_cache) == 0
214
214
  assert cg_client.profile_cache == {}
@@ -218,16 +218,16 @@ def test_clear_profile_cache_removes_all_entries(cg_client: ContentGridApplicati
218
218
  # Populate cache with some data
219
219
  test_data1 = {"_links": {"self": {"href": "/profile/entity1"}}, "name": "entity1"}
220
220
  test_data2 = {"_links": {"self": {"href": "/profile/entity2"}}, "name": "entity2"}
221
-
221
+
222
222
  cg_client.load_profile_cache("/profile/entity1", test_data1)
223
223
  cg_client.load_profile_cache("/profile/entity2", test_data2)
224
-
224
+
225
225
  # Verify entries are in cache
226
226
  assert len(cg_client.profile_cache) >= 2
227
-
227
+
228
228
  # Clear cache
229
229
  cg_client.clear_profile_cache()
230
-
230
+
231
231
  # Verify cache is empty
232
232
  assert len(cg_client.profile_cache) == 0
233
233
  assert "/profile/entity1" not in cg_client.profile_cache
@@ -238,15 +238,15 @@ def test_clear_profile_cache_allows_repopulation(cg_client: ContentGridApplicati
238
238
  # Populate cache
239
239
  profile1 = cg_client.get_profile()
240
240
  assert len(cg_client.profile_cache) > 0
241
-
241
+
242
242
  # Clear cache
243
243
  cg_client.clear_profile_cache()
244
244
  assert len(cg_client.profile_cache) == 0
245
-
245
+
246
246
  # Repopulate cache - should work normally
247
247
  profile2 = cg_client.get_profile()
248
248
  assert len(cg_client.profile_cache) > 0
249
-
249
+
250
250
  # Data should be consistent
251
251
  assert profile1.data == profile2.data
252
252
 
@@ -254,14 +254,14 @@ def test_clear_profile_cache_doesnt_affect_caching_flag(cg_client: ContentGridAp
254
254
  """Test that clearing cache doesn't disable caching"""
255
255
  # Check caching is enabled
256
256
  assert cg_client.use_profile_cache is True
257
-
257
+
258
258
  # Load and clear cache
259
259
  cg_client.load_profile_cache("/profile/test", {"name": "test"})
260
260
  cg_client.clear_profile_cache()
261
-
261
+
262
262
  # Caching should still be enabled
263
263
  assert cg_client.use_profile_cache is True
264
-
264
+
265
265
  # Cache should still work
266
266
  cg_client.get_profile()
267
267
  assert len(cg_client.profile_cache) > 0
@@ -272,14 +272,14 @@ def test_clear_profile_cache_forces_fresh_request(cg_client: ContentGridApplicat
272
272
  cg_client.get_profile()
273
273
  cache_size_after_first = len(cg_client.profile_cache)
274
274
  assert cache_size_after_first > 0
275
-
275
+
276
276
  # Clear cache
277
277
  cg_client.clear_profile_cache()
278
278
  assert len(cg_client.profile_cache) == 0
279
-
279
+
280
280
  # Next request should repopulate cache (new request made)
281
281
  cg_client.get_profile()
282
282
  cache_size_after_clear = len(cg_client.profile_cache)
283
-
283
+
284
284
  # Cache should be populated again
285
285
  assert cache_size_after_clear > 0
@@ -1,8 +0,0 @@
1
- {
2
- "tag": "0.2.9",
3
- "distance": 0,
4
- "node": "gb651e852c776cf5978adb8a0bd8a52662b8dd34b",
5
- "dirty": false,
6
- "branch": "HEAD",
7
- "node_date": "2026-08-12"
8
- }