langflow-base-nightly 0.5.0.dev33__py3-none-any.whl → 0.5.0.dev35__py3-none-any.whl

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 (171) hide show
  1. langflow/alembic/versions/1cb603706752_modify_uniqueness_constraint_on_file_.py +279 -0
  2. langflow/api/v1/endpoints.py +1 -1
  3. langflow/base/composio/composio_base.py +1092 -126
  4. langflow/components/agents/mcp_component.py +21 -4
  5. langflow/components/composio/__init__.py +24 -0
  6. langflow/components/composio/composio_api.py +116 -136
  7. langflow/components/composio/dropbox_compnent.py +11 -0
  8. langflow/components/composio/github_composio.py +1 -639
  9. langflow/components/composio/gmail_composio.py +26 -394
  10. langflow/components/composio/googlecalendar_composio.py +2 -778
  11. langflow/components/composio/googlemeet_composio.py +11 -0
  12. langflow/components/composio/googletasks_composio.py +8 -0
  13. langflow/components/composio/linear_composio.py +11 -0
  14. langflow/components/composio/outlook_composio.py +1 -755
  15. langflow/components/composio/reddit_composio.py +11 -0
  16. langflow/components/composio/slack_composio.py +1 -576
  17. langflow/components/composio/slackbot_composio.py +11 -0
  18. langflow/components/composio/supabase_composio.py +11 -0
  19. langflow/components/composio/todoist_composio.py +11 -0
  20. langflow/components/composio/youtube_composio.py +11 -0
  21. langflow/components/data/kb_ingest.py +15 -16
  22. langflow/components/processing/save_file.py +31 -4
  23. langflow/custom/utils.py +30 -7
  24. langflow/frontend/assets/{SlackIcon-Bikuxo8x.js → SlackIcon-B260Qg_R.js} +1 -1
  25. langflow/frontend/assets/{Wikipedia-B6aCFf5-.js → Wikipedia-BB2mbgyd.js} +1 -1
  26. langflow/frontend/assets/{Wolfram-CekL_M-a.js → Wolfram-DytXC9hF.js} +1 -1
  27. langflow/frontend/assets/{index-D1RgjMON.js → index-3TJWUdmx.js} +1 -1
  28. langflow/frontend/assets/{index-B4xLpgbM.js → index-3qMh9x6K.js} +1 -1
  29. langflow/frontend/assets/{index-DEuXrfXH.js → index-3uOAA_XX.js} +1 -1
  30. langflow/frontend/assets/{index-DTJX3yQa.js → index-4eRtaV45.js} +1 -1
  31. langflow/frontend/assets/index-7xXgqu09.js +1 -0
  32. langflow/frontend/assets/{index-BRNhftot.js → index-AY5Dm2mG.js} +1 -1
  33. langflow/frontend/assets/{index-4Tl3Nxdo.js → index-AlJ7td-D.js} +1 -1
  34. langflow/frontend/assets/{index-D2nHdRne.js → index-B-c82Fnu.js} +1 -1
  35. langflow/frontend/assets/{index-C3RZz8WE.js → index-B2ggrBuR.js} +1 -1
  36. langflow/frontend/assets/{index-in188l0A.js → index-B536IPXH.js} +1 -1
  37. langflow/frontend/assets/{index-CP0tFKwN.js → index-B5ed-sAv.js} +1 -1
  38. langflow/frontend/assets/{index-CAzSTGAM.js → index-B8TlNgn-.js} +1 -1
  39. langflow/frontend/assets/{index-09CVJwsY.js → index-B8y58M9b.js} +1 -1
  40. langflow/frontend/assets/{index-B9uOBe6Y.js → index-B9Mo3ndZ.js} +1 -1
  41. langflow/frontend/assets/{index-DAJafn16.js → index-BCK-ZyIh.js} +1 -1
  42. langflow/frontend/assets/{index-Cy-ZEfWh.js → index-BEDxAk3N.js} +1 -1
  43. langflow/frontend/assets/{index-DbmqjLy6.js → index-BEKoRwsX.js} +1 -1
  44. langflow/frontend/assets/{index-BcqeL_f4.js → index-BIkqesA-.js} +1 -1
  45. langflow/frontend/assets/{index-7x3wNZ-4.js → index-BJrY2Fiu.js} +1 -1
  46. langflow/frontend/assets/{index-Iamzh9ZT.js → index-BKvKC-12.js} +1 -1
  47. langflow/frontend/assets/{index-COqjpsdy.js → index-BLROcaSz.js} +1 -1
  48. langflow/frontend/assets/{index-BRwkzs92.js → index-BNbWMmAV.js} +1 -1
  49. langflow/frontend/assets/{index-C_UkF-RJ.js → index-BOEf7-ty.js} +1 -1
  50. langflow/frontend/assets/index-BOYTBrh9.js +1 -0
  51. langflow/frontend/assets/{index-DDcpxWU4.js → index-BQB-iDYl.js} +1 -1
  52. langflow/frontend/assets/{index-Crq_yhkG.js → index-BRWNIt9F.js} +1 -1
  53. langflow/frontend/assets/{index-DmaQAn3K.js → index-BVHvIhT5.js} +1 -1
  54. langflow/frontend/assets/{index-Cs_jt3dj.js → index-BVtf6m9S.js} +1 -1
  55. langflow/frontend/assets/{index-T2jJOG85.js → index-BWq9GTzt.js} +1 -1
  56. langflow/frontend/assets/{index-Dz0r9Idb.js → index-BXMhmvTj.js} +1 -1
  57. langflow/frontend/assets/{index-eJwu5YEi.js → index-Ba3RTMXI.js} +1 -1
  58. langflow/frontend/assets/{index-xVx59Op-.js → index-Baka5dKE.js} +1 -1
  59. langflow/frontend/assets/{index-DnusMCK1.js → index-BbsND1Qg.js} +1 -1
  60. langflow/frontend/assets/index-BcgB3rXH.js +1 -0
  61. langflow/frontend/assets/{index-CmiRgF_-.js → index-BdIWbCEL.js} +1 -1
  62. langflow/frontend/assets/{index-BllNr21U.js → index-BdYgKk1d.js} +1 -1
  63. langflow/frontend/assets/{index-BIKbxmIh.js → index-BeNby7qF.js} +1 -1
  64. langflow/frontend/assets/{index-CUe1ivTn.js → index-BejHxU5W.js} +1 -1
  65. langflow/frontend/assets/{index-CVphnxXi.js → index-Bisa4IQF.js} +1 -1
  66. langflow/frontend/assets/{index-Cr2oy5K2.js → index-BjENqyKe.js} +1 -1
  67. langflow/frontend/assets/{index-CEn_71Wk.js → index-BlBl2tvQ.js} +1 -1
  68. langflow/frontend/assets/{index-DOb9c2bf.js → index-BnLT29qW.js} +1 -1
  69. langflow/frontend/assets/{index-BRizlHaN.js → index-BqUeOc7Y.js} +1 -1
  70. langflow/frontend/assets/{index-D7nFs6oq.js → index-BsBWP-Dh.js} +1 -1
  71. langflow/frontend/assets/{index-BlRTHXW5.js → index-BtJ2o21k.js} +1 -1
  72. langflow/frontend/assets/{index-AOX7bbjJ.js → index-BxWXWRmZ.js} +1 -1
  73. langflow/frontend/assets/{index-B20KmxhS.js → index-BxkZkBgQ.js} +1 -1
  74. langflow/frontend/assets/{index-DoFlaGDx.js → index-Bxml6wXu.js} +1 -1
  75. langflow/frontend/assets/{index-B9KRIJFi.js → index-ByFXr9Iq.js} +1 -1
  76. langflow/frontend/assets/{index-CY6LUi4V.js → index-C2Xd7UkR.js} +1 -1
  77. langflow/frontend/assets/index-C76aBV_h.js +1 -0
  78. langflow/frontend/assets/{index-9gkURvG2.js → index-C7V5U9yH.js} +1 -1
  79. langflow/frontend/assets/{index-BDmbsLY2.js → index-C7x9R_Yo.js} +1 -1
  80. langflow/frontend/assets/{index-DI0zAExi.js → index-C8KD3LPb.js} +1 -1
  81. langflow/frontend/assets/{index-DzDNhMMW.js → index-C9N80hP8.js} +1 -1
  82. langflow/frontend/assets/{index-6GWpsedd.js → index-CDFLVFB4.js} +1 -1
  83. langflow/frontend/assets/{index-pkOi9P45.js → index-CF4dtI6S.js} +1 -1
  84. langflow/frontend/assets/{index-CdwjD4IX.js → index-CG7cp0nD.js} +1 -1
  85. langflow/frontend/assets/{index-J0pvFqLk.js → index-CHFO5O4g.js} +1 -1
  86. langflow/frontend/assets/{index-5G402gB8.js → index-CJwYfDBz.js} +1 -1
  87. langflow/frontend/assets/{index-BzCjyHto.js → index-CMGZGIx_.js} +1 -1
  88. langflow/frontend/assets/{index-Bm7a2vMS.js → index-COL0eiWI.js} +1 -1
  89. langflow/frontend/assets/{index-JHCxbvlW.js → index-CWWo2zOA.js} +1 -1
  90. langflow/frontend/assets/{index-C7wDSVVH.js → index-C_1RBTul.js} +1 -1
  91. langflow/frontend/assets/{index-BIjUtp6d.js → index-Ccb5B8zG.js} +1 -1
  92. langflow/frontend/assets/{index-yIh6-LZT.js → index-Cd5zuUUK.js} +1 -1
  93. langflow/frontend/assets/{index-CPIdMJkX.js → index-CkQ-bJ4G.js} +1 -1
  94. langflow/frontend/assets/{index-TRyDa01A.js → index-CkSzjCqM.js} +1 -1
  95. langflow/frontend/assets/{index-CSRizl2S.js → index-CoUlHbtg.js} +1 -1
  96. langflow/frontend/assets/index-Cpgkb0Q3.js +1 -0
  97. langflow/frontend/assets/{index-Cp7Pmn03.js → index-CqDUqHfd.js} +1 -1
  98. langflow/frontend/assets/{index-CGVDXKtN.js → index-Ct9_T9ox.js} +1 -1
  99. langflow/frontend/assets/{index-BwlYjc56.js → index-CvQ0w8Pj.js} +1 -1
  100. langflow/frontend/assets/{index-DkJCCraf.js → index-CwIxqYlT.js} +1 -1
  101. langflow/frontend/assets/{index-Bgd7yLoW.js → index-Cx__T92e.js} +1 -1
  102. langflow/frontend/assets/{index-RveG4dl9.js → index-D-zkHcob.js} +1 -1
  103. langflow/frontend/assets/{index-DVV_etfW.js → index-D0HmkH0H.js} +1 -1
  104. langflow/frontend/assets/{index-CglSqvB5.js → index-D0s9f6Re.js} +1 -1
  105. langflow/frontend/assets/{index-J98sU-1p.js → index-D5PeCofu.js} +1 -1
  106. langflow/frontend/assets/{index-BJIsQS8D.js → index-D87Zw62M.js} +1 -1
  107. langflow/frontend/assets/{index-FYcoJPMP.js → index-D9eflZfP.js} +1 -1
  108. langflow/frontend/assets/{index-DJs6FoYC.js → index-DDNNv4C0.js} +1 -1
  109. langflow/frontend/assets/index-DHlEwAxb.js +1 -0
  110. langflow/frontend/assets/{index-DqDQk0Cu.js → index-DIqSyDVO.js} +1 -1
  111. langflow/frontend/assets/{index-DOI0ceS-.js → index-DK8vNpXK.js} +1 -1
  112. langflow/frontend/assets/{index-D29n5mus.js → index-DKEXZFUO.js} +1 -1
  113. langflow/frontend/assets/{index-dfaj9-hY.js → index-DPX6X_bw.js} +1 -1
  114. langflow/frontend/assets/{index-CgbINWS8.js → index-DS1EgA10.js} +1 -1
  115. langflow/frontend/assets/{index-C69gdJqw.js → index-DS9I4y48.js} +1 -1
  116. langflow/frontend/assets/{index-B2EmwqKj.js → index-DWkMJnbd.js} +1 -1
  117. langflow/frontend/assets/{index-CIYzjH2y.js → index-DWr_zPkx.js} +1 -1
  118. langflow/frontend/assets/{index-D-HTZ68O.js → index-DX7XsAcx.js} +1 -1
  119. langflow/frontend/assets/{index-Cq30cQcP.js → index-DZzbmg3J.js} +1 -1
  120. langflow/frontend/assets/{index-BZCt_UnJ.js → index-DasrI03Y.js} +1 -1
  121. langflow/frontend/assets/index-DdzVmJHE.js +1 -0
  122. langflow/frontend/assets/{index-DmvjdU1N.js → index-DhzEUXfr.js} +1 -1
  123. langflow/frontend/assets/{index-B_ytx_iA.js → index-DpJiH-Rk.js} +1 -1
  124. langflow/frontend/assets/{index-Cyk3aCmP.js → index-DpQKtcXu.js} +1 -1
  125. langflow/frontend/assets/{index-DrvRK4_i.js → index-Dpz3oBf5.js} +1 -1
  126. langflow/frontend/assets/{index-DF0oWRdd.js → index-DqSH4x-R.js} +1 -1
  127. langflow/frontend/assets/{index-DX_InNVT.js → index-DtJyCbzF.js} +1 -1
  128. langflow/frontend/assets/{index-B4AtFbkN.js → index-Du9aJK7m.js} +1 -1
  129. langflow/frontend/assets/{index-qXcoVIRo.js → index-DuAeoC-H.js} +1 -1
  130. langflow/frontend/assets/{index-D7Vx6mgS.js → index-DxIs8VSp.js} +1 -1
  131. langflow/frontend/assets/{index-U7J1YiWE.js → index-DyJDHm2D.js} +1 -1
  132. langflow/frontend/assets/{index-1MEYR1La.js → index-DzeIsaBm.js} +1 -1
  133. langflow/frontend/assets/{index-Cbwk3f-p.js → index-DztLFiip.js} +1 -1
  134. langflow/frontend/assets/{index-C_2G2ZqJ.js → index-GODbXlHC.js} +1 -1
  135. langflow/frontend/assets/{index-2vQdFIK_.js → index-G_U_kPAd.js} +1 -1
  136. langflow/frontend/assets/{index-DS4F_Phe.js → index-IFGgPiye.js} +1 -1
  137. langflow/frontend/assets/{index-5hW8VleF.js → index-LrMzDsq9.js} +1 -1
  138. langflow/frontend/assets/{index-L7FKc9QN.js → index-R7q8cAek.js} +1 -1
  139. langflow/frontend/assets/{index-BRE8A4Q_.js → index-Uq2ij_SS.js} +1 -1
  140. langflow/frontend/assets/{index-Bn4HAVDG.js → index-VHmUHUUU.js} +1 -1
  141. langflow/frontend/assets/{index-VO-pk-Hg.js → index-VZnN0P6C.js} +1 -1
  142. langflow/frontend/assets/{index-Dy7ehgeV.js → index-VcXZzovW.js} +1 -1
  143. langflow/frontend/assets/{index-DNS4La1f.js → index-Ym6gz0T6.js} +1 -1
  144. langflow/frontend/assets/{index-UI2ws3qp.js → index-ci4XHjbJ.js} +176 -176
  145. langflow/frontend/assets/{index-DlMAYATX.js → index-dkS0ek2S.js} +1 -1
  146. langflow/frontend/assets/{index-Dc0p1Oxl.js → index-hOkEW3JP.js} +1 -1
  147. langflow/frontend/assets/{index-KnS52ylc.js → index-js8ceOaP.js} +1 -1
  148. langflow/frontend/assets/{index-DtCsjX48.js → index-lKEJpUsF.js} +1 -1
  149. langflow/frontend/assets/{index-BO4fl1uU.js → index-mBjJYD9q.js} +1 -1
  150. langflow/frontend/assets/{index-C_K6Tof7.js → index-r1LZg-PY.js} +1 -1
  151. langflow/frontend/assets/index-rcdQpNcU.js +1 -0
  152. langflow/frontend/assets/{index-_3qag0I4.js → index-sS6XLk3j.js} +1 -1
  153. langflow/frontend/assets/{index-C6P0vvSP.js → index-tOy_uloT.js} +1 -1
  154. langflow/frontend/assets/lazyIconImports-Bh1TFfvH.js +2 -0
  155. langflow/frontend/assets/{use-post-add-user-Bt6vZvvT.js → use-post-add-user-HN0rRnhv.js} +1 -1
  156. langflow/frontend/index.html +1 -1
  157. langflow/initial_setup/starter_projects/Knowledge Ingestion.json +2 -2
  158. langflow/initial_setup/starter_projects/News Aggregator.json +19 -2
  159. langflow/initial_setup/starter_projects/Nvidia Remix.json +19 -2
  160. langflow/interface/initialize/loading.py +3 -1
  161. langflow/main.py +19 -2
  162. langflow/services/database/models/file/model.py +4 -2
  163. langflow/services/database/service.py +3 -1
  164. langflow/services/telemetry/schema.py +7 -0
  165. langflow/services/telemetry/service.py +25 -0
  166. langflow/services/tracing/service.py +14 -4
  167. {langflow_base_nightly-0.5.0.dev33.dist-info → langflow_base_nightly-0.5.0.dev35.dist-info}/METADATA +1 -1
  168. {langflow_base_nightly-0.5.0.dev33.dist-info → langflow_base_nightly-0.5.0.dev35.dist-info}/RECORD +170 -152
  169. langflow/frontend/assets/lazyIconImports-kvf_Kak2.js +0 -2
  170. {langflow_base_nightly-0.5.0.dev33.dist-info → langflow_base_nightly-0.5.0.dev35.dist-info}/WHEEL +0 -0
  171. {langflow_base_nightly-0.5.0.dev33.dist-info → langflow_base_nightly-0.5.0.dev35.dist-info}/entry_points.txt +0 -0
@@ -139,8 +139,8 @@ class KBIngestionComponent(Component):
139
139
  {
140
140
  "column_name": "text",
141
141
  "vectorize": True,
142
- "identifier": False,
143
- }
142
+ "identifier": True,
143
+ },
144
144
  ],
145
145
  ),
146
146
  IntInput(
@@ -187,9 +187,8 @@ class KBIngestionComponent(Component):
187
187
  df_columns = set(df_source.columns)
188
188
  for config in config_list:
189
189
  col_name = config.get("column_name")
190
- if col_name not in df_columns and not self.silent_errors:
190
+ if col_name not in df_columns:
191
191
  msg = f"Column '{col_name}' not found in DataFrame. Available columns: {sorted(df_columns)}"
192
- self.log(f"Warning: {msg}")
193
192
  raise ValueError(msg)
194
193
 
195
194
  return config_list
@@ -295,9 +294,7 @@ class KBIngestionComponent(Component):
295
294
  if not cfg_path.exists():
296
295
  cfg_path.write_text(json.dumps(config_list, indent=2))
297
296
 
298
- except Exception as e:
299
- if not self.silent_errors:
300
- raise
297
+ except (OSError, TypeError, ValueError) as e:
301
298
  self.log(f"Error saving KB files: {e}")
302
299
 
303
300
  def _build_column_metadata(self, config_list: list[dict[str, Any]], df_source: pd.DataFrame) -> dict[str, Any]:
@@ -367,9 +364,7 @@ class KBIngestionComponent(Component):
367
364
  chroma.add_documents(documents)
368
365
  self.log(f"Added {len(documents)} documents to vector store '{self.knowledge_base}'")
369
366
 
370
- except Exception as e:
371
- if not self.silent_errors:
372
- raise
367
+ except (OSError, ValueError, RuntimeError) as e:
373
368
  self.log(f"Error creating vector store: {e}")
374
369
 
375
370
  def _convert_df_to_data_objects(self, df_source: pd.DataFrame, config_list: list[dict[str, Any]]) -> list[Data]:
@@ -407,16 +402,22 @@ class KBIngestionComponent(Component):
407
402
 
408
403
  # Convert each row to a Data object
409
404
  for _, row in df_source.iterrows():
410
- # Build content text from vectorized columns using list comprehension
411
- content_parts = [str(row[col]) for col in content_cols if col in row and pd.notna(row[col])]
405
+ # Build content text from identifier columns using list comprehension
406
+ identifier_parts = [str(row[col]) for col in content_cols if col in row and pd.notna(row[col])]
412
407
 
413
- page_content = " ".join(content_parts)
408
+ # Join all parts into a single string
409
+ page_content = " ".join(identifier_parts)
414
410
 
415
411
  # Build metadata from NON-vectorized columns only (simple key-value pairs)
416
412
  data_dict = {
417
413
  "text": page_content, # Main content for vectorization
418
414
  }
419
415
 
416
+ # Add identifier columns if they exist
417
+ if identifier_cols:
418
+ identifier_parts = [str(row[col]) for col in identifier_cols if col in row and pd.notna(row[col])]
419
+ page_content = " ".join(identifier_parts)
420
+
420
421
  # Add metadata columns as simple key-value pairs
421
422
  for col in df_source.columns:
422
423
  if col not in content_cols and col in row and pd.notna(row[col]):
@@ -526,9 +527,7 @@ class KBIngestionComponent(Component):
526
527
 
527
528
  return Data(data=meta)
528
529
 
529
- except Exception as e:
530
- if not self.silent_errors:
531
- raise
530
+ except (OSError, ValueError, RuntimeError, KeyError) as e:
532
531
  self.log(f"Error in KB ingestion: {e}")
533
532
  self.status = f"❌ KB ingestion failed: {e}"
534
533
  return Data(data={"error": str(e), "kb_name": self.knowledge_base})
@@ -1,6 +1,7 @@
1
1
  import json
2
2
  from collections.abc import AsyncIterator, Iterator
3
3
  from pathlib import Path
4
+ from typing import TYPE_CHECKING
4
5
 
5
6
  import orjson
6
7
  import pandas as pd
@@ -9,13 +10,16 @@ from fastapi.encoders import jsonable_encoder
9
10
 
10
11
  from langflow.api.v2.files import upload_user_file
11
12
  from langflow.custom import Component
12
- from langflow.io import DropdownInput, HandleInput, StrInput
13
+ from langflow.io import DropdownInput, HandleInput, SecretStrInput, StrInput
13
14
  from langflow.schema import Data, DataFrame, Message
14
- from langflow.services.auth.utils import create_user_longterm_token
15
+ from langflow.services.auth.utils import create_user_longterm_token, get_current_user
15
16
  from langflow.services.database.models.user.crud import get_user_by_id
16
17
  from langflow.services.deps import get_session, get_settings_service, get_storage_service
17
18
  from langflow.template.field.base import Output
18
19
 
20
+ if TYPE_CHECKING:
21
+ from langflow.services.database.models.user.model import User
22
+
19
23
 
20
24
  class SaveToFileComponent(Component):
21
25
  display_name = "Save File"
@@ -51,6 +55,13 @@ class SaveToFileComponent(Component):
51
55
  value="",
52
56
  advanced=True,
53
57
  ),
58
+ SecretStrInput(
59
+ name="api_key",
60
+ display_name="Langflow API Key",
61
+ info="Langflow API key for authentication when saving the file.",
62
+ required=False,
63
+ advanced=True,
64
+ ),
54
65
  ]
55
66
 
56
67
  outputs = [Output(display_name="File Path", name="message", method="save_to_file")]
@@ -138,8 +149,24 @@ class SaveToFileComponent(Component):
138
149
 
139
150
  with file_path.open("rb") as f:
140
151
  async for db in get_session():
141
- user_id, _ = await create_user_longterm_token(db)
142
- current_user = await get_user_by_id(db, user_id)
152
+ # TODO: In 1.6, this may need to be removed or adjusted
153
+ # Try to get the super user token, if possible
154
+ current_user: User | None = None
155
+ if self.api_key:
156
+ current_user = await get_current_user(
157
+ token="",
158
+ query_param=self.api_key,
159
+ header_param="",
160
+ db=db,
161
+ )
162
+ else:
163
+ user_id, _ = await create_user_longterm_token(db)
164
+ current_user = await get_user_by_id(db, user_id)
165
+
166
+ # Fail if the user is not found
167
+ if not current_user:
168
+ msg = "User not found. Please provide a valid API key or ensure the user exists."
169
+ raise ValueError(msg)
143
170
 
144
171
  await upload_user_file(
145
172
  file=UploadFile(filename=file_path.name, file=f, size=file_path.stat().st_size),
langflow/custom/utils.py CHANGED
@@ -33,13 +33,12 @@ from langflow.utils import validate
33
33
  from langflow.utils.util import get_base_classes
34
34
 
35
35
 
36
- def _generate_code_hash(source_code: str, modname: str, class_name: str) -> str:
36
+ def _generate_code_hash(source_code: str, modname: str) -> str:
37
37
  """Generate a hash of the component source code.
38
38
 
39
39
  Args:
40
40
  source_code: The source code string
41
41
  modname: The module name for context
42
- class_name: The class name for context
43
42
 
44
43
  Returns:
45
44
  SHA256 hash of the source code
@@ -50,7 +49,7 @@ def _generate_code_hash(source_code: str, modname: str, class_name: str) -> str:
50
49
  TypeError: If source_code is not a string
51
50
  """
52
51
  if not source_code:
53
- msg = f"Empty source code for {class_name} in {modname}"
52
+ msg = f"Empty source code for {modname}"
54
53
  raise ValueError(msg)
55
54
 
56
55
  # Generate SHA256 hash of the source code
@@ -439,6 +438,18 @@ def add_code_field_to_build_config(build_config: dict, raw_code: str):
439
438
  return build_config
440
439
 
441
440
 
441
+ def get_module_name_from_display_name(display_name: str):
442
+ """Get the module name from the display name."""
443
+ # Convert display name to snake_case for Python module name
444
+ # e.g., "Custom Component" -> "custom_component"
445
+ # Remove extra spaces and convert to lowercase
446
+ cleaned_name = re.sub(r"\s+", " ", display_name.strip())
447
+ # Replace spaces with underscores and convert to lowercase
448
+ module_name = cleaned_name.replace(" ", "_").lower()
449
+ # Remove any non-alphanumeric characters except underscores
450
+ return re.sub(r"[^a-z0-9_]", "", module_name)
451
+
452
+
442
453
  def build_custom_component_template_from_inputs(
443
454
  custom_component: Component | CustomComponent, user_id: str | UUID | None = None, module_name: str | None = None
444
455
  ):
@@ -479,11 +490,17 @@ def build_custom_component_template_from_inputs(
479
490
  reorder_fields(frontend_node, cc_instance._get_field_order())
480
491
  if module_name:
481
492
  frontend_node.metadata["module"] = module_name
493
+ else:
494
+ module_name = get_module_name_from_display_name(frontend_node.display_name)
495
+ frontend_node.metadata["module"] = f"custom_components.{module_name}"
482
496
 
483
- # Generate code hash for cache invalidation and debugging
484
- code_hash = _generate_code_hash(custom_component._code, module_name, ctype_name)
497
+ # Generate code hash for cache invalidation and debugging
498
+ try:
499
+ code_hash = _generate_code_hash(custom_component._code, module_name)
485
500
  if code_hash:
486
501
  frontend_node.metadata["code_hash"] = code_hash
502
+ except Exception as exc: # noqa: BLE001
503
+ logger.opt(exception=exc).debug(f"Error generating code hash for {custom_component.__class__.__name__}")
487
504
 
488
505
  return frontend_node.to_dict(keep_name=False), cc_instance
489
506
 
@@ -546,11 +563,17 @@ def build_custom_component_template(
546
563
 
547
564
  if module_name:
548
565
  frontend_node.metadata["module"] = module_name
566
+ else:
567
+ module_name = get_module_name_from_display_name(frontend_node.display_name)
568
+ frontend_node.metadata["module"] = f"custom_components.{module_name}"
549
569
 
550
- # Generate code hash for cache invalidation and debugging
551
- code_hash = _generate_code_hash(custom_component._code, module_name, custom_component.__class__.__name__)
570
+ # Generate code hash for cache invalidation and debugging
571
+ try:
572
+ code_hash = _generate_code_hash(custom_component._code, module_name)
552
573
  if code_hash:
553
574
  frontend_node.metadata["code_hash"] = code_hash
575
+ except Exception as exc: # noqa: BLE001
576
+ logger.opt(exception=exc).debug(f"Error generating code hash for {custom_component.__class__.__name__}")
554
577
 
555
578
  return frontend_node.to_dict(keep_name=False), custom_instance
556
579
  except Exception as exc:
@@ -1 +1 @@
1
- import{j as a}from"./index-UI2ws3qp.js";const s=l=>a.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 54 54",width:"1em",height:"1em",...l,children:a.jsxs("g",{fill:"none",fillRule:"evenodd",children:[a.jsx("path",{fill:"#36C5F0",d:"M19.712.133a5.381 5.381 0 0 0-5.376 5.387 5.381 5.381 0 0 0 5.376 5.386h5.376V5.52A5.381 5.381 0 0 0 19.712.133m0 14.365H5.376A5.381 5.381 0 0 0 0 19.884a5.381 5.381 0 0 0 5.376 5.387h14.336a5.381 5.381 0 0 0 5.376-5.387 5.381 5.381 0 0 0-5.376-5.386"}),a.jsx("path",{fill:"#2EB67D",d:"M53.76 19.884a5.381 5.381 0 0 0-5.376-5.386 5.381 5.381 0 0 0-5.376 5.386v5.387h5.376a5.381 5.381 0 0 0 5.376-5.387m-14.336 0V5.52A5.381 5.381 0 0 0 34.048.133a5.381 5.381 0 0 0-5.376 5.387v14.364a5.381 5.381 0 0 0 5.376 5.387 5.381 5.381 0 0 0 5.376-5.387"}),a.jsx("path",{fill:"#ECB22E",d:"M34.048 54a5.381 5.381 0 0 0 5.376-5.387 5.381 5.381 0 0 0-5.376-5.386h-5.376v5.386A5.381 5.381 0 0 0 34.048 54m0-14.365h14.336a5.381 5.381 0 0 0 5.376-5.386 5.381 5.381 0 0 0-5.376-5.387H34.048a5.381 5.381 0 0 0-5.376 5.387 5.381 5.381 0 0 0 5.376 5.386"}),a.jsx("path",{fill:"#E01E5A",d:"M0 34.249a5.381 5.381 0 0 0 5.376 5.386 5.381 5.381 0 0 0 5.376-5.386v-5.387H5.376A5.381 5.381 0 0 0 0 34.25m14.336-.001v14.364A5.381 5.381 0 0 0 19.712 54a5.381 5.381 0 0 0 5.376-5.387V34.25a5.381 5.381 0 0 0-5.376-5.387 5.381 5.381 0 0 0-5.376 5.387"})]})});export{s as default};
1
+ import{j as a}from"./index-ci4XHjbJ.js";const s=l=>a.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 54 54",width:"1em",height:"1em",...l,children:a.jsxs("g",{fill:"none",fillRule:"evenodd",children:[a.jsx("path",{fill:"#36C5F0",d:"M19.712.133a5.381 5.381 0 0 0-5.376 5.387 5.381 5.381 0 0 0 5.376 5.386h5.376V5.52A5.381 5.381 0 0 0 19.712.133m0 14.365H5.376A5.381 5.381 0 0 0 0 19.884a5.381 5.381 0 0 0 5.376 5.387h14.336a5.381 5.381 0 0 0 5.376-5.387 5.381 5.381 0 0 0-5.376-5.386"}),a.jsx("path",{fill:"#2EB67D",d:"M53.76 19.884a5.381 5.381 0 0 0-5.376-5.386 5.381 5.381 0 0 0-5.376 5.386v5.387h5.376a5.381 5.381 0 0 0 5.376-5.387m-14.336 0V5.52A5.381 5.381 0 0 0 34.048.133a5.381 5.381 0 0 0-5.376 5.387v14.364a5.381 5.381 0 0 0 5.376 5.387 5.381 5.381 0 0 0 5.376-5.387"}),a.jsx("path",{fill:"#ECB22E",d:"M34.048 54a5.381 5.381 0 0 0 5.376-5.387 5.381 5.381 0 0 0-5.376-5.386h-5.376v5.386A5.381 5.381 0 0 0 34.048 54m0-14.365h14.336a5.381 5.381 0 0 0 5.376-5.386 5.381 5.381 0 0 0-5.376-5.387H34.048a5.381 5.381 0 0 0-5.376 5.387 5.381 5.381 0 0 0 5.376 5.386"}),a.jsx("path",{fill:"#E01E5A",d:"M0 34.249a5.381 5.381 0 0 0 5.376 5.386 5.381 5.381 0 0 0 5.376-5.386v-5.387H5.376A5.381 5.381 0 0 0 0 34.25m14.336-.001v14.364A5.381 5.381 0 0 0 19.712 54a5.381 5.381 0 0 0 5.376-5.387V34.25a5.381 5.381 0 0 0-5.376-5.387 5.381 5.381 0 0 0-5.376 5.387"})]})});export{s as default};