upgini 1.2.125__tar.gz → 1.2.127__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.

Potentially problematic release.


This version of upgini might be problematic. Click here for more details.

Files changed (82) hide show
  1. {upgini-1.2.125 → upgini-1.2.127}/PKG-INFO +1 -1
  2. upgini-1.2.127/src/upgini/__about__.py +1 -0
  3. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/data_source/data_source_publisher.py +1 -9
  4. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/features_enricher.py +41 -22
  5. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/metadata.py +1 -0
  6. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/resource_bundle/strings.properties +2 -1
  7. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/display_utils.py +44 -7
  8. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/feature_info.py +18 -7
  9. upgini-1.2.125/src/upgini/__about__.py +0 -1
  10. {upgini-1.2.125 → upgini-1.2.127}/.gitignore +0 -0
  11. {upgini-1.2.125 → upgini-1.2.127}/LICENSE +0 -0
  12. {upgini-1.2.125 → upgini-1.2.127}/README.md +0 -0
  13. {upgini-1.2.125 → upgini-1.2.127}/pyproject.toml +0 -0
  14. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/__init__.py +0 -0
  15. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/ads.py +0 -0
  16. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/ads_management/__init__.py +0 -0
  17. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/ads_management/ads_manager.py +0 -0
  18. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/autofe/__init__.py +0 -0
  19. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/autofe/all_operators.py +0 -0
  20. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/autofe/binary.py +0 -0
  21. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/autofe/date.py +0 -0
  22. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/autofe/feature.py +0 -0
  23. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/autofe/groupby.py +0 -0
  24. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/autofe/operator.py +0 -0
  25. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/autofe/timeseries/__init__.py +0 -0
  26. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/autofe/timeseries/base.py +0 -0
  27. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/autofe/timeseries/cross.py +0 -0
  28. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/autofe/timeseries/delta.py +0 -0
  29. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/autofe/timeseries/lag.py +0 -0
  30. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/autofe/timeseries/roll.py +0 -0
  31. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/autofe/timeseries/trend.py +0 -0
  32. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/autofe/timeseries/volatility.py +0 -0
  33. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/autofe/unary.py +0 -0
  34. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/autofe/utils.py +0 -0
  35. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/autofe/vector.py +0 -0
  36. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/data_source/__init__.py +0 -0
  37. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/dataset.py +0 -0
  38. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/errors.py +0 -0
  39. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/http.py +0 -0
  40. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/mdc/__init__.py +0 -0
  41. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/mdc/context.py +0 -0
  42. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/metrics.py +0 -0
  43. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/normalizer/__init__.py +0 -0
  44. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/normalizer/normalize_utils.py +0 -0
  45. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/resource_bundle/__init__.py +0 -0
  46. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/resource_bundle/exceptions.py +0 -0
  47. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/resource_bundle/strings_widget.properties +0 -0
  48. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/sampler/__init__.py +0 -0
  49. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/sampler/base.py +0 -0
  50. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/sampler/random_under_sampler.py +0 -0
  51. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/sampler/utils.py +0 -0
  52. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/search_task.py +0 -0
  53. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/spinner.py +0 -0
  54. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/Roboto-Regular.ttf +0 -0
  55. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/__init__.py +0 -0
  56. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/base_search_key_detector.py +0 -0
  57. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/blocked_time_series.py +0 -0
  58. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/config.py +0 -0
  59. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/country_utils.py +0 -0
  60. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/custom_loss_utils.py +0 -0
  61. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/cv_utils.py +0 -0
  62. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/datetime_utils.py +0 -0
  63. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/deduplicate_utils.py +0 -0
  64. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/email_utils.py +0 -0
  65. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/fallback_progress_bar.py +0 -0
  66. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/features_validator.py +0 -0
  67. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/format.py +0 -0
  68. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/hash_utils.py +0 -0
  69. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/ip_utils.py +0 -0
  70. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/mstats.py +0 -0
  71. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/phone_utils.py +0 -0
  72. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/postal_code_utils.py +0 -0
  73. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/progress_bar.py +0 -0
  74. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/psi.py +0 -0
  75. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/sample_utils.py +0 -0
  76. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/sklearn_ext.py +0 -0
  77. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/sort.py +0 -0
  78. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/target_utils.py +0 -0
  79. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/track_info.py +0 -0
  80. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/ts_utils.py +0 -0
  81. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/utils/warning_counter.py +0 -0
  82. {upgini-1.2.125 → upgini-1.2.127}/src/upgini/version_validator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: upgini
3
- Version: 1.2.125
3
+ Version: 1.2.127
4
4
  Summary: Intelligent data search & enrichment for Machine Learning
5
5
  Project-URL: Bug Reports, https://github.com/upgini/upgini/issues
6
6
  Project-URL: Homepage, https://upgini.com/
@@ -0,0 +1 @@
1
+ __version__ = "1.2.127"
@@ -123,17 +123,9 @@ class DataSourcePublisher:
123
123
  set(search_keys.values()) == {SearchKey.IP_RANGE_FROM, SearchKey.IP_RANGE_TO}
124
124
  or set(search_keys.values()) == {SearchKey.IPV6_RANGE_FROM, SearchKey.IPV6_RANGE_TO}
125
125
  or set(search_keys.values()) == {SearchKey.MSISDN_RANGE_FROM, SearchKey.MSISDN_RANGE_TO}
126
+ or snapshot_frequency_days is not None or join_date_abs_limit_days is not None
126
127
  ) and sort_column is None:
127
128
  raise ValidationError("Sort column is required for passed search keys")
128
- if (
129
- set(search_keys.values()) == {SearchKey.PHONE, SearchKey.DATE}
130
- and snapshot_frequency_days is None
131
- and join_date_abs_limit_days is None
132
- ):
133
- raise ValidationError(
134
- "With MSISDN and DATE keys one of the snapshot_frequency_days or"
135
- " join_date_abs_limit_days parameters is required"
136
- )
137
129
  if (
138
130
  set(search_keys.values()) == {SearchKey.PHONE, SearchKey.DATE}
139
131
  or set(search_keys.values()) == {SearchKey.HEM, SearchKey.DATE}
@@ -1479,11 +1479,7 @@ class FeaturesEnricher(TransformerMixin):
1479
1479
 
1480
1480
  self.logger.info(f"PSI values by sparsity: {psi_values_sparse}")
1481
1481
 
1482
- unstable_by_sparsity = [
1483
- feature
1484
- for feature, psi in psi_values_sparse.items()
1485
- if psi > stability_threshold
1486
- ]
1482
+ unstable_by_sparsity = [feature for feature, psi in psi_values_sparse.items() if psi > stability_threshold]
1487
1483
  if unstable_by_sparsity:
1488
1484
  self.logger.info(f"Unstable by sparsity features ({stability_threshold}): {sorted(unstable_by_sparsity)}")
1489
1485
 
@@ -1493,11 +1489,7 @@ class FeaturesEnricher(TransformerMixin):
1493
1489
 
1494
1490
  self.logger.info(f"PSI values by value: {psi_values}")
1495
1491
 
1496
- unstable_by_value = [
1497
- feature
1498
- for feature, psi in psi_values.items()
1499
- if psi > stability_threshold
1500
- ]
1492
+ unstable_by_value = [feature for feature, psi in psi_values.items() if psi > stability_threshold]
1501
1493
  if unstable_by_value:
1502
1494
  self.logger.info(f"Unstable by value features ({stability_threshold}): {sorted(unstable_by_value)}")
1503
1495
 
@@ -2561,10 +2553,15 @@ if response.status_code == 200:
2561
2553
  if transform_usage.has_limit:
2562
2554
  if len(X) > transform_usage.rest_rows:
2563
2555
  rest_rows = max(transform_usage.rest_rows, 0)
2564
- msg = self.bundle.get("transform_usage_warning").format(len(X), rest_rows)
2556
+ bundle_msg = (
2557
+ "transform_usage_warning_registered"
2558
+ if self.__is_registered
2559
+ else "transform_usage_warning_demo"
2560
+ )
2561
+ msg = self.bundle.get(bundle_msg).format(len(X), rest_rows)
2565
2562
  self.logger.warning(msg)
2566
2563
  print(msg)
2567
- show_request_quote_button()
2564
+ show_request_quote_button(is_registered=self.__is_registered)
2568
2565
  return None, {}, [], {}
2569
2566
  else:
2570
2567
  msg = self.bundle.get("transform_usage_info").format(
@@ -2749,8 +2746,13 @@ if response.status_code == 200:
2749
2746
 
2750
2747
  meaning_types = {}
2751
2748
  meaning_types.update(
2752
- {col: FileColumnMeaningType.FEATURE for col in features_for_transform if col not in date_features}
2749
+ {
2750
+ col: FileColumnMeaningType.FEATURE
2751
+ for col in features_for_transform
2752
+ if col not in date_features and col not in generated_features
2753
+ }
2753
2754
  )
2755
+ meaning_types.update({col: FileColumnMeaningType.GENERATED_FEATURE for col in generated_features})
2754
2756
  meaning_types.update({col: FileColumnMeaningType.DATE_FEATURE for col in date_features})
2755
2757
  meaning_types.update({col: key.value for col, key in search_keys.items()})
2756
2758
 
@@ -3304,9 +3306,10 @@ if response.status_code == 200:
3304
3306
  **{
3305
3307
  str(c): FileColumnMeaningType.FEATURE
3306
3308
  for c in df.columns
3307
- if c not in non_feature_columns and c not in date_features
3309
+ if c not in non_feature_columns and c not in date_features and c not in self.fit_generated_features
3308
3310
  },
3309
3311
  }
3312
+ meaning_types.update({col: FileColumnMeaningType.GENERATED_FEATURE for col in self.fit_generated_features})
3310
3313
  meaning_types.update({col: FileColumnMeaningType.DATE_FEATURE for col in date_features})
3311
3314
  meaning_types[self.TARGET_NAME] = FileColumnMeaningType.TARGET
3312
3315
  meaning_types[ENTITY_SYSTEM_RECORD_ID] = FileColumnMeaningType.ENTITY_SYSTEM_RECORD_ID
@@ -3368,7 +3371,12 @@ if response.status_code == 200:
3368
3371
  self.passed_features = [
3369
3372
  column
3370
3373
  for column, meaning_type in meaning_types.items()
3371
- if meaning_type in [FileColumnMeaningType.FEATURE, FileColumnMeaningType.DATE_FEATURE]
3374
+ if meaning_type
3375
+ in [
3376
+ FileColumnMeaningType.FEATURE,
3377
+ FileColumnMeaningType.DATE_FEATURE,
3378
+ FileColumnMeaningType.GENERATED_FEATURE,
3379
+ ]
3372
3380
  ]
3373
3381
 
3374
3382
  self._search_task = dataset.search(
@@ -4433,7 +4441,9 @@ if response.status_code == 200:
4433
4441
  raise Exception(self.bundle.get("missing_features_meta"))
4434
4442
  features_meta = deepcopy(features_meta)
4435
4443
 
4436
- original_names_dict = {c.name: c.originalName for c in self._search_task.get_file_metadata(trace_id).columns}
4444
+ file_metadata_columns = self._search_task.get_file_metadata(trace_id).columns
4445
+ file_meta_by_orig_name = {c.originalName: c for c in file_metadata_columns}
4446
+ original_names_dict = {c.name: c.originalName for c in file_metadata_columns}
4437
4447
  features_df = self._search_task.get_all_initial_raw_features(trace_id, metrics_calculation=True)
4438
4448
 
4439
4449
  # To be sure that names with hash suffixes
@@ -4453,7 +4463,11 @@ if response.status_code == 200:
4453
4463
  original_name = original_names_dict.get(feature_meta.name, feature_meta.name)
4454
4464
  feature_meta.name = original_name
4455
4465
 
4456
- is_client_feature = original_name in clients_features_df.columns
4466
+ file_meta = file_meta_by_orig_name.get(original_name)
4467
+ is_generated_feature = (
4468
+ file_meta is not None and file_meta.meaningType == FileColumnMeaningType.GENERATED_FEATURE
4469
+ )
4470
+ is_client_feature = original_name in clients_features_df.columns and not is_generated_feature
4457
4471
 
4458
4472
  if selected_features is not None and feature_meta.name not in selected_features:
4459
4473
  self.logger.info(f"Feature {feature_meta.name} is not selected before and skipped")
@@ -4476,9 +4490,13 @@ if response.status_code == 200:
4476
4490
 
4477
4491
  for feature_meta in selected_features_meta:
4478
4492
  original_name = original_names_dict.get(feature_meta.name, feature_meta.name)
4479
- is_client_feature = original_name in clients_features_df.columns
4493
+ file_meta = file_meta_by_orig_name.get(original_name)
4494
+ is_generated_feature = (
4495
+ file_meta is not None and file_meta.meaningType == FileColumnMeaningType.GENERATED_FEATURE
4496
+ )
4497
+ is_client_feature = original_name in clients_features_df.columns and not is_generated_feature
4480
4498
 
4481
- if not is_client_feature:
4499
+ if not is_client_feature and not is_generated_feature:
4482
4500
  self.external_source_feature_names.append(original_name)
4483
4501
 
4484
4502
  if self.psi_values is not None:
@@ -4509,9 +4527,10 @@ if response.status_code == 200:
4509
4527
 
4510
4528
  self.feature_names_.append(feature_meta.name)
4511
4529
  self.feature_importances_.append(_round_shap_value(feature_meta.shap_value))
4512
-
4513
4530
  df_for_sample = features_df if feature_meta.name in features_df.columns else clients_features_df
4514
- feature_info = FeatureInfo.from_metadata(feature_meta, df_for_sample, is_client_feature)
4531
+ feature_info = FeatureInfo.from_metadata(
4532
+ feature_meta, df_for_sample, is_client_feature, is_generated_feature
4533
+ )
4515
4534
  features_info.append(feature_info.to_row(self.bundle))
4516
4535
  features_info_without_links.append(feature_info.to_row_without_links(self.bundle))
4517
4536
  internal_features_info.append(feature_info.to_internal_row(self.bundle))
@@ -4522,7 +4541,7 @@ if response.status_code == 200:
4522
4541
  if len(features_info) > 0:
4523
4542
  self.features_info = pd.DataFrame(features_info)
4524
4543
  # If all psi values are 0 or null, drop psi column
4525
- if self.features_info[self.bundle.get("features_info_psi")].fillna(0.0).eq(0.0).all():
4544
+ if self.features_info[self.bundle.get("features_info_psi")].astype(np.float64).fillna(0.0).eq(0.0).all():
4526
4545
  self.features_info.drop(columns=[self.bundle.get("features_info_psi")], inplace=True)
4527
4546
  self._features_info_without_links = pd.DataFrame(features_info_without_links)
4528
4547
  self._internal_features_info = pd.DataFrame(internal_features_info)
@@ -36,6 +36,7 @@ class FileColumnMeaningType(Enum):
36
36
  SCORE = "SCORE"
37
37
  TARGET = "TARGET"
38
38
  FEATURE = "FEATURE"
39
+ GENERATED_FEATURE = "GENERATED_FEATURE"
39
40
  DATE_FEATURE = "DATE_FEATURE"
40
41
  CUSTOM_KEY = "CUSTOM_KEY"
41
42
  COUNTRY = "COUNTRY"
@@ -12,7 +12,8 @@ polling_unregister_information=We'll send email notification once it's completed
12
12
  ads_upload_finish=Thank you for your submission!\nWe'll check your data sharing proposal and get back to you
13
13
  demo_dataset_info=Demo training dataset detected. Registration for an API key is not required.\n
14
14
  transform_usage_info=You use Trial access to Upgini data enrichment. Limit for Trial: {} rows. You have already enriched: {} rows.
15
- transform_usage_warning=You are trying to launch enrichment for {} rows, which will exceed the rest limit {}.
15
+ transform_usage_warning_demo=Unregistered-user limit: {} rows remaining; you requested {}.
16
+ transform_usage_warning_registered=Free tier limit: {} rows remaining; you requested {}.
16
17
 
17
18
  # Warnings
18
19
  support_link=https://upgini.com/support
@@ -339,17 +339,54 @@ def show_button_download_pdf(
339
339
  return display(HTML(html), display_id=display_id)
340
340
 
341
341
 
342
- def show_request_quote_button():
342
+ def show_request_quote_button(is_registered: bool):
343
343
  if not ipython_available():
344
- print("https://upgini.com/request-a-quote")
344
+ if is_registered:
345
+ print("https://upgini.com/request-a-quote")
346
+ else:
347
+ print("https://profile.upgini.com/login")
345
348
  else:
346
- import ipywidgets as widgets
347
- from IPython.display import Javascript, display
348
-
349
- button = widgets.Button(description="Request a quote", button_style="danger")
349
+ from IPython.display import HTML, display, Javascript
350
+ from ipywidgets import Layout, Button
351
+
352
+ if is_registered:
353
+ display(HTML("""
354
+ <style>
355
+ button.custom-button {
356
+ border: 1px solid black !important;
357
+ background: white !important;
358
+ color: black !important;
359
+ white-space: nowrap;
360
+ }
361
+ </style>
362
+ """))
363
+ description = "Request a quote"
364
+ tooltip = "Ask a quote"
365
+ url = "https://upgini.com/request-a-quote"
366
+ else:
367
+ display(HTML("""
368
+ <style>
369
+ button.custom-button {
370
+ border: 1px solid #d00 !important;
371
+ background: #fff !important;
372
+ color: #d00 !important;
373
+ white-space: nowrap;
374
+ }
375
+ </style>
376
+ """))
377
+ description = "Get an API KEY"
378
+ tooltip = "Register"
379
+ url = "https://profile.upgini.com/login"
380
+
381
+ button = Button(
382
+ description=description,
383
+ layout=Layout(width='auto'),
384
+ tooltip=tooltip
385
+ )
386
+ button.add_class("custom-button")
350
387
 
351
388
  def on_button_clicked(b):
352
- display(Javascript('window.open("https://upgini.com/request-a-quote");'))
389
+ display(Javascript('window.open("' + url + '");'))
353
390
 
354
391
  button.on_click(on_button_clicked)
355
392
 
@@ -31,7 +31,10 @@ class FeatureInfo:
31
31
 
32
32
  @staticmethod
33
33
  def from_metadata(
34
- feature_meta: FeaturesMetadataV2, data: Optional[pd.DataFrame], is_client_feature: bool
34
+ feature_meta: FeaturesMetadataV2,
35
+ data: Optional[pd.DataFrame],
36
+ is_client_feature: bool,
37
+ is_generated_feature: bool,
35
38
  ) -> "FeatureInfo":
36
39
  return FeatureInfo(
37
40
  name=_get_name(feature_meta),
@@ -41,8 +44,8 @@ class FeatureInfo:
41
44
  value_preview=_get_feature_sample(feature_meta, data),
42
45
  provider=_get_provider(feature_meta, is_client_feature),
43
46
  internal_provider=_get_internal_provider(feature_meta, is_client_feature),
44
- source=_get_source(feature_meta, is_client_feature),
45
- internal_source=_get_internal_source(feature_meta, is_client_feature),
47
+ source=_get_source(feature_meta, is_client_feature, is_generated_feature),
48
+ internal_source=_get_internal_source(feature_meta, is_client_feature, is_generated_feature),
46
49
  update_frequency=feature_meta.update_frequency,
47
50
  commercial_schema=feature_meta.commercial_schema,
48
51
  doc_link=feature_meta.doc_link,
@@ -139,22 +142,30 @@ def _get_internal_provider(feature_meta: FeaturesMetadataV2, is_client_feature:
139
142
  return "" if is_client_feature else (feature_meta.data_provider or "Upgini")
140
143
 
141
144
 
142
- def _get_source(feature_meta: FeaturesMetadataV2, is_client_feature: bool) -> str:
145
+ def _get_source(feature_meta: FeaturesMetadataV2, is_client_feature: bool, is_generated_feature: bool) -> str:
146
+ if is_generated_feature:
147
+ return "AutoFE: features from Training dataset"
148
+
143
149
  sources = _list_or_single(feature_meta.data_sources, feature_meta.data_source)
144
150
  source_links = _list_or_single(feature_meta.data_source_links, feature_meta.data_source_link)
145
151
  if sources:
146
152
  source = _make_links(sources, source_links)
147
153
  else:
148
- source = _get_internal_source(feature_meta, is_client_feature)
154
+ source = _get_internal_source(feature_meta, is_client_feature, is_generated_feature)
149
155
  return source
150
156
 
151
157
 
152
- def _get_internal_source(feature_meta: FeaturesMetadataV2, is_client_feature: bool) -> str:
158
+ def _get_internal_source(feature_meta: FeaturesMetadataV2, is_client_feature: bool, is_generated_feature: bool) -> str:
159
+ if is_generated_feature:
160
+ return "AutoFE: features from Training dataset"
161
+
153
162
  sources = _list_or_single(feature_meta.data_sources, feature_meta.data_source)
154
163
  if sources:
155
164
  return ", ".join(sources)
165
+ elif feature_meta.data_source:
166
+ return feature_meta.data_source
156
167
  else:
157
- return feature_meta.data_source or (
168
+ return (
158
169
  LLM_SOURCE
159
170
  if not feature_meta.name.endswith("_country")
160
171
  and not feature_meta.name.endswith("_postal_code")
@@ -1 +0,0 @@
1
- __version__ = "1.2.125"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes