surfdataverse 4.0.0__tar.gz → 4.0.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: surfdataverse
3
- Version: 4.0.0
3
+ Version: 4.0.1
4
4
  Summary: A Python package for ionysis Microsoft Dataverse integration
5
5
  Keywords: dataverse,microsoft,crm,api
6
6
  Author: ionysis
@@ -76,8 +76,8 @@ client.get_authenticated_session()
76
76
  client.test_connection()
77
77
 
78
78
  # Create entities/tables using modern DI factory functions
79
- product = connect_entity("logical_table_name_1", "prefix_")
80
- table_reader = connect_table("logical_table_name_1", "prefix_")
79
+ product = connect_entity("logical_table_name_1")
80
+ table_reader = connect_table("logical_table_name_1")
81
81
 
82
82
  # Set data using write() method with automatic type detection
83
83
  product.write("prefix_name", "My Product")
@@ -167,7 +167,7 @@ default_entity = connect_entity("prefix_tablename", "prefix_")
167
167
  custom_entity = connect_entity("myorg_product", "myorg_")
168
168
 
169
169
  # For reading data
170
- table_reader = connect_table("prefix_tablename", "prefix_")
170
+ table_reader = connect_table("prefix_tablename")
171
171
 
172
172
  # The system automatically:
173
173
  # - Filters columns starting with your prefix
@@ -183,7 +183,7 @@ Fetch data from Dataverse tables as pandas DataFrames using modern DI patterns:
183
183
  from surfdataverse import connect_table, get_client
184
184
 
185
185
  # Create table reader using dependency injection
186
- table_reader = connect_table("logical_table_name_1", "prefix_")
186
+ table_reader = connect_table("logical_table_name_1")
187
187
 
188
188
  # Get table data as pandas DataFrame
189
189
  df = table_reader.get_table_data()
@@ -47,8 +47,8 @@ client.get_authenticated_session()
47
47
  client.test_connection()
48
48
 
49
49
  # Create entities/tables using modern DI factory functions
50
- product = connect_entity("logical_table_name_1", "prefix_")
51
- table_reader = connect_table("logical_table_name_1", "prefix_")
50
+ product = connect_entity("logical_table_name_1")
51
+ table_reader = connect_table("logical_table_name_1")
52
52
 
53
53
  # Set data using write() method with automatic type detection
54
54
  product.write("prefix_name", "My Product")
@@ -138,7 +138,7 @@ default_entity = connect_entity("prefix_tablename", "prefix_")
138
138
  custom_entity = connect_entity("myorg_product", "myorg_")
139
139
 
140
140
  # For reading data
141
- table_reader = connect_table("prefix_tablename", "prefix_")
141
+ table_reader = connect_table("prefix_tablename")
142
142
 
143
143
  # The system automatically:
144
144
  # - Filters columns starting with your prefix
@@ -154,7 +154,7 @@ Fetch data from Dataverse tables as pandas DataFrames using modern DI patterns:
154
154
  from surfdataverse import connect_table, get_client
155
155
 
156
156
  # Create table reader using dependency injection
157
- table_reader = connect_table("logical_table_name_1", "prefix_")
157
+ table_reader = connect_table("logical_table_name_1")
158
158
 
159
159
  # Get table data as pandas DataFrame
160
160
  df = table_reader.get_table_data()
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "surfdataverse"
7
- version = "4.0.0"
7
+ version = "4.0.1"
8
8
  description = "A Python package for ionysis Microsoft Dataverse integration"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -34,14 +34,14 @@ def get_client(config_path=None) -> DataverseClient:
34
34
  return container.client()
35
35
 
36
36
 
37
- def connect_table(logical_name: str = "", prefix: str = "") -> DataverseTable:
37
+ def connect_table(logical_name: str = "") -> DataverseTable:
38
38
  """Connect to a Dataverse table"""
39
- return container.table_factory(logical_name, prefix)
39
+ return container.table_factory(logical_name)
40
40
 
41
41
 
42
- def connect_entity(table_logical_name: str, table_prefix: str = "") -> DataverseEntity:
42
+ def connect_entity(table_logical_name: str) -> DataverseEntity:
43
43
  """Connect to a new Dataverse entity instance"""
44
- return container.entity_factory(table_logical_name, table_prefix)
44
+ return container.entity_factory(table_logical_name)
45
45
 
46
46
 
47
47
  def reset_container():
@@ -194,7 +194,7 @@ class DataverseClient:
194
194
  class DataverseBase:
195
195
  """Base class for Dataverse operations with shared functionality"""
196
196
 
197
- def __init__(self, table_logical_name: str = "", prefix="", client=None):
197
+ def __init__(self, table_logical_name: str = "", client=None):
198
198
  if client is None:
199
199
  raise ValueError(
200
200
  "Client is required. Use connect_entity() or connect_table() instead of direct instantiation."
@@ -202,10 +202,7 @@ class DataverseBase:
202
202
  self.client = client
203
203
 
204
204
  self.table_logical_name = table_logical_name
205
- self.table_logical_name_prefix = prefix
206
- self.name = (
207
- table_logical_name.replace(self.table_logical_name_prefix, "").title().replace("_", " ")
208
- )
205
+ self.name = table_logical_name.title().replace("_", " ")
209
206
 
210
207
  # Stored values for this session
211
208
  self._guid_mapping = {}
@@ -215,7 +212,6 @@ class DataverseBase:
215
212
  self._table_metadata = {}
216
213
  self._table_definitions = {}
217
214
  self._table_relationships = {}
218
- self._filtered_choices = {}
219
215
 
220
216
  # === RELATIONSHIPS
221
217
  @property
@@ -278,17 +274,6 @@ class DataverseBase:
278
274
 
279
275
  return self._global_choices
280
276
 
281
- @property
282
- def filtered_choices(self):
283
- """Get choices filtered by table prefix"""
284
- if not self._filtered_choices:
285
- self._filtered_choices = {
286
- name: options
287
- for name, options in self.global_choices.items()
288
- if self.table_logical_name_prefix in name
289
- }
290
- return self._filtered_choices
291
-
292
277
  # === TABLES
293
278
  def get_table_definitions(self):
294
279
  if not self._table_definitions:
@@ -683,14 +668,13 @@ class DataverseTable(DataverseBase):
683
668
  class DataverseEntity(DataverseBase):
684
669
  """Generic class for Dataverse entities"""
685
670
 
686
- def __init__(self, table_logical_name, table_prefix="", client=None):
671
+ def __init__(self, table_logical_name, client=None):
687
672
  """
688
673
  Args:
689
674
  table_logical_name: The pluralized name of the Dataverse table
690
- table_prefix: The prefix used for custom table/column names (default: "prefix_")
691
675
  client: Optional DataverseClient instance (will create singleton if not provided)
692
676
  """
693
- super().__init__(table_logical_name, table_prefix, client)
677
+ super().__init__(table_logical_name, client)
694
678
 
695
679
  self.guid = None
696
680
  self.data = {} # Dictionary to store record fields
@@ -722,7 +706,7 @@ class DataverseEntity(DataverseBase):
722
706
  elif column in self.get_table_relationships():
723
707
  self.set_lookup(column, value)
724
708
  # Choice columns (picklist/option sets)
725
- elif column in self.filtered_choices:
709
+ elif column in self.global_choices:
726
710
  self.set_choice(column, value)
727
711
  # Regular data columns (including DateTime, String, Integer, Decimal, etc.)
728
712
  else:
@@ -762,7 +746,7 @@ class DataverseEntity(DataverseBase):
762
746
  elif column in self.get_table_relationships():
763
747
  return self.get_lookup(column)
764
748
  # Choice columns (picklist/option sets)
765
- elif column in self.filtered_choices:
749
+ elif column in self.global_choices:
766
750
  return self.get_choice(column)
767
751
  # Regular data columns (including DateTime, String, Integer, Decimal, etc.)
768
752
  else:
@@ -793,8 +777,7 @@ class DataverseEntity(DataverseBase):
793
777
 
794
778
  # Update our data with the fresh record
795
779
  for field, fresh_value in record.items():
796
- if field.startswith(self.table_logical_name_prefix) or field.endswith("id"):
797
- self.data[field] = fresh_value
780
+ self.data[field] = fresh_value
798
781
 
799
782
  logger.info(f"Refreshed data for {self.table_logical_name} GUID: {self.guid}")
800
783
  return True
@@ -837,8 +820,7 @@ class DataverseEntity(DataverseBase):
837
820
 
838
821
  # Update our data with the fresh record
839
822
  for field, fresh_value in record.items():
840
- if field.startswith(self.table_logical_name_prefix) or field.endswith("id"):
841
- self.data[field] = fresh_value
823
+ self.data[field] = fresh_value
842
824
 
843
825
  # Return the requested value
844
826
  value = self.data.get(column, "")
@@ -875,7 +857,7 @@ class DataverseEntity(DataverseBase):
875
857
  # === CHOICE
876
858
  def set_choice(self, column, value):
877
859
  """Adds a choice field by looking up its numeric value"""
878
- choice_value = self.filtered_choices[column].get(value) # Get numeric value for choice
860
+ choice_value = self.global_choices[column].get(value) # Get numeric value for choice
879
861
  if choice_value is not None:
880
862
  self.data[column] = choice_value
881
863
  else:
@@ -885,7 +867,7 @@ class DataverseEntity(DataverseBase):
885
867
 
886
868
  def get_choice(self, column):
887
869
  """Retrieves the readable choice name from its stored numeric value (Int → String)"""
888
- choice_dict = self.filtered_choices.get(column, {})
870
+ choice_dict = self.global_choices.get(column, {})
889
871
  choices_invert = {v: k for k, v in choice_dict.items()} # Invert dict for reverse lookup
890
872
  numeric_value = self.data.get(column, None)
891
873
  return choices_invert.get(numeric_value, None)