alita-sdk 0.3.117__py3-none-any.whl → 0.3.119__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.
@@ -15,7 +15,7 @@ from elitea_analyse.jira.jira_issues import JiraIssues
15
15
 
16
16
  from alita_tools.elitea_base import BaseToolApiWrapper
17
17
  from ....tools.artifact import ArtifactWrapper
18
-
18
+ from ....utils.logging import with_streamlit_logs
19
19
 
20
20
  logger = logging.getLogger(__name__)
21
21
 
@@ -59,9 +59,21 @@ class JiraAnalyseWrapper(BaseToolApiWrapper):
59
59
  Get projects a user has access to and merge them with issues count.
60
60
  after_date: str
61
61
  date after which issues are considered
62
+ project_keys: str
63
+ one or more projects keys separated with comma
62
64
  """
63
65
  project_keys = project_keys or self.project_keys
64
66
 
67
+ dispatch_custom_event(
68
+ name="thinking_step",
69
+ data={
70
+ "message": f"I am extracting number of all issues with initial parameters:\
71
+ project keys: {project_keys}, after date: {after_date}",
72
+ "tool_name": "get_number_off_all_issues",
73
+ "toolkit": "analyse_jira",
74
+ },
75
+ )
76
+
65
77
  project_df = jira_projects_overview(
66
78
  after_date, project_keys=project_keys, jira=self.jira
67
79
  )
@@ -72,22 +84,12 @@ class JiraAnalyseWrapper(BaseToolApiWrapper):
72
84
  f"projects_overview_{project_keys}.csv",
73
85
  csv_options={"index": False},
74
86
  )
75
- dispatch_custom_event(
76
- name="jira_projects_overview",
77
- data={
78
- "project_keys": project_keys,
79
- "after_date": after_date,
80
- "files": [f"projects_overview_{project_keys}.csv"],
81
- "project_count": len(project_df),
82
- "columns": project_df.columns.tolist(),
83
- },
84
- )
85
-
86
87
  return {
87
88
  "projects": project_df["key"].tolist(),
88
89
  "projects_summary": project_df.to_string(),
89
90
  }
90
91
 
92
+ @with_streamlit_logs(tool_name="get_jira_issues")
91
93
  def get_jira_issues(
92
94
  self,
93
95
  closed_issues_based_on: int,
@@ -100,7 +102,8 @@ class JiraAnalyseWrapper(BaseToolApiWrapper):
100
102
  """
101
103
  Extract Jira issues for the specified projects.
102
104
  closed_issues_based_on: int
103
- define whether issues can be thought as closed based on their status (1) or not empty resolved date (2)
105
+ define whether issues can be thought as
106
+ closed based on their status (1) or not empty resolved date (2)
104
107
  resolved_after: str
105
108
  resolved after date (i.e. 2023-01-01)
106
109
  updated_after: str
@@ -112,6 +115,7 @@ class JiraAnalyseWrapper(BaseToolApiWrapper):
112
115
  project_keys: str
113
116
  one or more projects keys separated with comma
114
117
  """
118
+
115
119
  if not (
116
120
  (
117
121
  closed_issues_based_on == 1
@@ -122,7 +126,7 @@ class JiraAnalyseWrapper(BaseToolApiWrapper):
122
126
  return (
123
127
  "ERROR: Check input parameters closed_issues_based_on and closed_status"
124
128
  )
125
-
129
+
126
130
  project_keys = project_keys or self.project_keys
127
131
 
128
132
  dispatch_custom_event(
@@ -1,6 +1,7 @@
1
1
  from io import BytesIO
2
- from typing import Optional
2
+ from typing import Optional, List
3
3
 
4
+ import requests
4
5
  from PIL import Image
5
6
  from langchain_community.document_loaders import ConfluenceLoader
6
7
  from langchain_community.document_loaders.confluence import ContentFormat
@@ -9,7 +10,7 @@ from pdf2image import convert_from_bytes
9
10
  from reportlab.graphics import renderPM
10
11
  from svglib.svglib import svg2rlg
11
12
 
12
- from ..tools.utils import image_to_byte_array, bytes_to_base64
13
+ from src.alita_sdk.langchain.tools.utils import image_to_byte_array, bytes_to_base64
13
14
 
14
15
  Image.MAX_IMAGE_PIXELS = 300_000_000
15
16
 
@@ -73,6 +74,61 @@ class AlitaConfluenceLoader(ConfluenceLoader):
73
74
  kwargs['content_format'] = mapping.get(content_formant, ContentFormat.VIEW)
74
75
  return super().load(**kwargs)
75
76
 
77
+ def process_attachment(
78
+ self,
79
+ page_id: str,
80
+ ocr_languages: Optional[str] = None,
81
+ ) -> List[str]:
82
+ """
83
+ Process attachments from a Confluence page and extract text from them.
84
+ Note: if the attachment is corrupted, it will be skipped and an error will be logged.
85
+ """
86
+
87
+ try:
88
+ from PIL import Image # noqa: F401
89
+ except ImportError:
90
+ raise ImportError(
91
+ "`Pillow` package not found, " "please run `pip install Pillow`"
92
+ )
93
+
94
+ attachments = self.confluence.get_attachments_from_content(page_id)["results"]
95
+ texts = []
96
+ for attachment in attachments:
97
+ media_type = attachment["metadata"]["mediaType"]
98
+ absolute_url = self.base_url + attachment["_links"]["download"]
99
+ title = attachment["title"]
100
+ try:
101
+ if media_type == "application/pdf":
102
+ text = title + self.process_pdf(absolute_url, ocr_languages)
103
+ elif (
104
+ media_type == "image/png"
105
+ or media_type == "image/jpg"
106
+ or media_type == "image/jpeg"
107
+ ):
108
+ text = title + self.process_image(absolute_url, ocr_languages)
109
+ elif (
110
+ media_type == "application/vnd.openxmlformats-officedocument"
111
+ ".wordprocessingml.document"
112
+ ):
113
+ text = title + self.process_doc(absolute_url)
114
+ elif media_type == "application/vnd.ms-excel":
115
+ text = title + self.process_xls(absolute_url)
116
+ # elif media_type == "image/svg+xml":
117
+ # text = title + self.process_svg(absolute_url, ocr_languages)
118
+ else:
119
+ continue
120
+ texts.append(text)
121
+ except requests.HTTPError as e:
122
+ if e.response.status_code == 404:
123
+ print(f"Attachment not found at {absolute_url}") # noqa: T201
124
+ continue
125
+ else:
126
+ raise
127
+ except Exception as e:
128
+ print(f"Error processing attachment {absolute_url}: {e}")
129
+ continue
130
+ return texts
131
+
76
132
  def process_pdf(
77
133
  self,
78
134
  link: str,
@@ -19,7 +19,7 @@ from ..document_loaders.AlitaCSVLoader import AlitaCSVLoader
19
19
  from ..document_loaders.AlitaExcelLoader import AlitaExcelLoader
20
20
  from ..document_loaders.AlitaDirectoryLoader import AlitaDirectoryLoader
21
21
  from ..document_loaders.AlitaGitRepoLoader import AlitaGitRepoLoader
22
- from ..document_loaders.AlitaConfluenceLoader import AlitaConfluenceLoader
22
+ from alita_tools.confluence.loader import AlitaConfluenceLoader
23
23
  from ..document_loaders.AlitaBDDScenariosLoader import BDDScenariosLoader
24
24
  from ..document_loaders.AlitaJiraLoader import AlitaJiraLoader
25
25
 
@@ -0,0 +1,93 @@
1
+ import logging
2
+ from functools import wraps
3
+
4
+ from langchain_core.callbacks import dispatch_custom_event
5
+
6
+
7
+ class StreamlitCallbackHandler(logging.Handler):
8
+ """Custom logging handler to send logs to Streamlit."""
9
+
10
+ def __init__(self, tool_name: str = "logging"):
11
+ super().__init__()
12
+ self.tool_name = tool_name
13
+
14
+ def emit(self, record):
15
+ """Emit a log record."""
16
+ if record.levelno < logging.INFO:
17
+ return # Ignore debug logs
18
+
19
+ log_entry = self.format(record)
20
+ dispatch_custom_event(
21
+ name="thinking_step",
22
+ data={
23
+ "message": log_entry,
24
+ "tool_name": self.tool_name,
25
+ "toolkit": "logging", # ? or pass the toolkit name
26
+ },
27
+ )
28
+
29
+
30
+ def setup_streamlit_logging(
31
+ logger_name: str = "", tool_name="logging"
32
+ ) -> StreamlitCallbackHandler:
33
+ """
34
+ Attach a StreamlitCallbackHandler to the given logger (default: root).
35
+ Returns the handler so you can remove it later if needed.
36
+ """
37
+ logger = logging.getLogger(logger_name)
38
+ handler = StreamlitCallbackHandler(tool_name)
39
+
40
+ # Avoid duplicate handlers
41
+ if not any(isinstance(h, StreamlitCallbackHandler) for h in logger.handlers):
42
+ formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
43
+ handler.setFormatter(formatter)
44
+ logger.addHandler(handler)
45
+
46
+ return handler
47
+
48
+
49
+ # Decorator version
50
+ def with_streamlit_logs(logger_name: str = "", tool_name="logging"):
51
+ """
52
+ Decorator to temporarily attach a StreamlitCallbackHandler to a function's logger.
53
+
54
+ Args:
55
+ logger_name (str): Name of the logger to attach the handler to.
56
+ Use an empty string "" for the root logger.
57
+ tool_name (str): Name of the tool to display in Streamlit logs.
58
+
59
+ Behavior:
60
+ - Attaches a StreamlitCallbackHandler before the function runs.
61
+ - Forwards all INFO and higher log messages—including those
62
+ from 3rd-party libraries using the specified logger—to Streamlit
63
+ via dispatch_custom_event.
64
+ - Automatically removes the handler after the function completes,
65
+ even if an exception occurs.
66
+
67
+ Example:
68
+ @with_streamlit_logs(logger_name="my_logger", tool_name="my_tool")
69
+ def my_function():
70
+ logging.info("This is a log message.")
71
+ # Logs from 3rd-party libraries using "my_logger" will also be sent to Streamlit.
72
+
73
+ Returns:
74
+ The decorated function with Streamlit logging enabled during its execution.
75
+ """
76
+
77
+ def decorator(func):
78
+ @wraps(func)
79
+ def wrapper(*args, **kwargs):
80
+ logger = logging.getLogger(logger_name)
81
+ handler = StreamlitCallbackHandler(tool_name=tool_name)
82
+ handler.setFormatter(
83
+ logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
84
+ )
85
+ logger.addHandler(handler)
86
+ try:
87
+ return func(*args, **kwargs)
88
+ finally:
89
+ logger.removeHandler(handler)
90
+
91
+ return wrapper
92
+
93
+ return decorator
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alita_sdk
3
- Version: 0.3.117
3
+ Version: 0.3.119
4
4
  Summary: SDK for building langchain agents using resouces from Alita
5
5
  Author-email: Artem Rozumenko <artyom.rozumenko@gmail.com>, Mikalai Biazruchka <mikalai_biazruchka@epam.com>, Roman Mitusov <roman_mitusov@epam.com>, Ivan Krakhmaliuk <lifedjik@gmail.com>
6
6
  Project-URL: Homepage, https://projectalita.ai
@@ -11,7 +11,7 @@ alita_sdk/community/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
11
11
  alita_sdk/community/utils.py,sha256=lvuCJaNqVPHOORJV6kIPcXJcdprVW_TJvERtYAEgpjM,249
12
12
  alita_sdk/community/analysis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  alita_sdk/community/analysis/jira_analyse/__init__.py,sha256=Rm-HKEi_HIxrgHdq9mZ-XzxMKLXm8-81eJwJT2lar-c,5945
14
- alita_sdk/community/analysis/jira_analyse/api_wrapper.py,sha256=FPYAOh2SV5ggWg0ywDdkyt6udyR3juQvZM7lOIwvcKU,9327
14
+ alita_sdk/community/analysis/jira_analyse/api_wrapper.py,sha256=JqGSxg_3x0ErzII31UZkY3V7jo9i8Gb5d_pW7lPIOSA,9522
15
15
  alita_sdk/community/browseruse/__init__.py,sha256=uAxPZEX7ihpt8HtcGDFrzTNv9WcklT1wG1ItTwUO8y4,3601
16
16
  alita_sdk/community/browseruse/api_wrapper.py,sha256=Y05NKWfTROPmBxe8ZFIELSGBX5v3RTNP30OTO2Tj8uI,10838
17
17
  alita_sdk/langchain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -27,7 +27,7 @@ alita_sdk/langchain/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
27
27
  alita_sdk/langchain/agents/xml_chat.py,sha256=Mx7PK5T97_GrFCwHHZ3JZP42S7MwtUzV0W-_8j6Amt8,6212
28
28
  alita_sdk/langchain/document_loaders/AlitaBDDScenariosLoader.py,sha256=4kFU1ijrM1Jw7cywQv8mUiBHlE6w-uqfzSZP4hUV5P4,3771
29
29
  alita_sdk/langchain/document_loaders/AlitaCSVLoader.py,sha256=TBJuIFqweLDtd0JxgfPqrcY5eED-M617CT_EInp6Lmg,1949
30
- alita_sdk/langchain/document_loaders/AlitaConfluenceLoader.py,sha256=ehCmV8uaSP9HY9fcBrgEa8j3-ATN5quMb8BDUERly90,5986
30
+ alita_sdk/langchain/document_loaders/AlitaConfluenceLoader.py,sha256=wpZxN9tKSzRACROu4NYQ020wuIVgvuI14_EPQ_CbrU4,8316
31
31
  alita_sdk/langchain/document_loaders/AlitaDirectoryLoader.py,sha256=fKezkgvIcLG7S2PVJp1a8sZd6C4XQKNZKAFC87DbQts,7003
32
32
  alita_sdk/langchain/document_loaders/AlitaDocxMammothLoader.py,sha256=dBf0JkWMrNBCB4zJ3fjtOxci0OzZuDimMGSPYS7W6Oo,4848
33
33
  alita_sdk/langchain/document_loaders/AlitaExcelLoader.py,sha256=fC7L_NzkGZSirYvJhXSbuc37e2FNtNgETQamkKVqcTQ,1457
@@ -42,7 +42,7 @@ alita_sdk/langchain/document_loaders/utils.py,sha256=ifh0UJiweIb2iEb2_THJy2pbAnT
42
42
  alita_sdk/langchain/interfaces/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
43
  alita_sdk/langchain/interfaces/kwextractor.py,sha256=kSJA9L8g8UArmHu7Bd9dIO0Rrq86JPUb8RYNlnN68FQ,3072
44
44
  alita_sdk/langchain/interfaces/llm_processor.py,sha256=oX5feXsQ5D-8q3Mf40Txltv3kkHKb2xBeNPwecy5yDQ,8442
45
- alita_sdk/langchain/interfaces/loaders.py,sha256=li-O2dubiDNYn-qfVcDsuD4LqP_IZ61cV2vHUZAqeXc,3337
45
+ alita_sdk/langchain/interfaces/loaders.py,sha256=7btXnGW-wODBoF5Jlv9ljPlkMzJU4NwA8E_v_VzsIHg,3326
46
46
  alita_sdk/langchain/interfaces/splitters.py,sha256=tW65-Ejj9VYyxXFZNgPts_CKILQ18bWp_1bZ-24FKGc,3630
47
47
  alita_sdk/langchain/retrievers/AlitaRetriever.py,sha256=osChtJxUlfpsFESpJSE5mnJAkxTXnzgFZnC6l5mUlbo,6148
48
48
  alita_sdk/langchain/retrievers/VectorstoreRetriever.py,sha256=CWZbqle5sjEWxFbmn1-ZuMYUgQLQb_b6sCK1d1KxeWE,2012
@@ -88,12 +88,13 @@ alita_sdk/tools/vectorstore.py,sha256=F-DoHxPa4UVsKB-FEd-wWa59QGQifKMwcSNcZ5WZOK
88
88
  alita_sdk/utils/AlitaCallback.py,sha256=cvpDhR4QLVCNQci6CO6TEUrUVDZU9_CRSwzcHGm3SGw,7356
89
89
  alita_sdk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
90
90
  alita_sdk/utils/evaluate.py,sha256=iM1P8gzBLHTuSCe85_Ng_h30m52hFuGuhNXJ7kB1tgI,1872
91
+ alita_sdk/utils/logging.py,sha256=hBE3qAzmcLMdamMp2YRXwOOK9P4lmNaNhM76kntVljs,3124
91
92
  alita_sdk/utils/streamlit.py,sha256=zp8owZwHI3HZplhcExJf6R3-APtWx-z6s5jznT2hY_k,29124
92
93
  alita_sdk/utils/utils.py,sha256=dM8whOJAuFJFe19qJ69-FLzrUp6d2G-G6L7d4ss2XqM,346
93
- alita_sdk-0.3.117.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
94
+ alita_sdk-0.3.119.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
94
95
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
95
96
  tests/test_jira_analysis.py,sha256=I0cErH5R_dHVyutpXrM1QEo7jfBuKWTmDQvJBPjx18I,3281
96
- alita_sdk-0.3.117.dist-info/METADATA,sha256=UKs2mCU1AvQTt5jMaeRngvrGk8z6WwY4DX6aNBmaEzo,7075
97
- alita_sdk-0.3.117.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
98
- alita_sdk-0.3.117.dist-info/top_level.txt,sha256=SWRhxB7Et3cOy3RkE5hR7OIRnHoo3K8EXzoiNlkfOmc,25
99
- alita_sdk-0.3.117.dist-info/RECORD,,
97
+ alita_sdk-0.3.119.dist-info/METADATA,sha256=Icr-9s7-kw-d_4ZHMiPJOkUgvyx_X5mB9xLYNiYWHj4,7075
98
+ alita_sdk-0.3.119.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
99
+ alita_sdk-0.3.119.dist-info/top_level.txt,sha256=SWRhxB7Et3cOy3RkE5hR7OIRnHoo3K8EXzoiNlkfOmc,25
100
+ alita_sdk-0.3.119.dist-info/RECORD,,