dure-waseem commited on
Commit
ae43d88
·
1 Parent(s): 91881f8

initial code

Browse files
Files changed (6) hide show
  1. config/agents.yaml +8 -0
  2. config/tasks.yaml +9 -0
  3. crew.py +111 -0
  4. main.py +247 -0
  5. requirements.txt +2 -0
  6. tools/custom_tool.py +91 -0
config/agents.yaml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ document_analyst:
2
+ role: >
3
+ Senior Document Analyst
4
+ goal: >
5
+ To analyze the document
6
+ backstory: >
7
+ You have a keen eye to details and you are able to analyze the document with precision.
8
+ You role is to analyze the document and extract the exact information from it.
config/tasks.yaml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ document_analysis:
2
+ description: >
3
+ Analyze the document and extract the exact information from it. {file_path} is the path of the document.
4
+ {file_type} is the type of the document.
5
+ expected_output: >
6
+ The document is analyzed and the exact information is extracted from it.
7
+ Return in Markdown format.
8
+ agent: document_analyst
9
+
crew.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # from crewai import Agent, Crew, Process, Task, LLM
2
+ # from crewai.project import CrewBase, agent, crew, task
3
+ # from tools.custom_tool import landing_ai_document_analysis
4
+ # from dotenv import load_dotenv
5
+ # import os
6
+ # # from langchain_groq import ChatGroq
7
+ # # Load environment variables
8
+ # load_dotenv()
9
+
10
+ # @CrewBase
11
+ # class DocProcessing():
12
+ # """DocProcessing crew"""
13
+
14
+ # agents_config = 'config/agents.yaml'
15
+ # tasks_config = 'config/tasks.yaml'
16
+
17
+ # llm = LLM(
18
+ # model = "claude-3-haiku-20240307",
19
+ # api_key = os.getenv("ANTHROPIC_API_KEY"),
20
+ # temperature = 0,
21
+ # )
22
+
23
+ # # llm = ChatGroq(
24
+ # # model = "groq/llama-3.1-8b-instant",
25
+ # # api_key= os.getenv("GROQ_API_KEY"),
26
+ # # )
27
+
28
+
29
+
30
+
31
+ # @agent
32
+ # def document_analyst(self) -> Agent:
33
+ # return Agent(
34
+ # config=self.agents_config['document_analyst'],
35
+ # verbose=True,
36
+ # tools=[landing_ai_document_analysis],
37
+ # llm=self.llm,
38
+ # )
39
+
40
+
41
+ # @task
42
+ # def document_analysis(self) -> Task:
43
+ # return Task(
44
+ # config=self.tasks_config['document_analysis'],
45
+ # )
46
+
47
+
48
+
49
+ # @crew
50
+ # def crew(self) -> Crew:
51
+ # """Creates the DocProcessing crew"""
52
+
53
+
54
+ # return Crew(
55
+ # agents=self.agents, # Automatically created by the @agent decorator
56
+ # tasks=self.tasks, # Automatically created by the @task decorator
57
+ # process=Process.sequential,
58
+ # verbose=True,
59
+ # )
60
+ from crewai import Agent, Crew, Process, Task, LLM
61
+ from crewai.project import CrewBase, agent, crew, task
62
+ from tools.custom_tool import landing_ai_document_analysis
63
+ import os
64
+
65
+ @CrewBase
66
+ class DocProcessing():
67
+ """DocProcessing crew for document analysis"""
68
+
69
+ agents_config = 'config/agents.yaml'
70
+ tasks_config = 'config/tasks.yaml'
71
+
72
+ def __init__(self):
73
+ """Initialize the DocProcessing crew with API key validation."""
74
+ super().__init__()
75
+
76
+ # Get API key from environment variable (set at runtime)
77
+ anthropic_api_key = os.getenv("ANTHROPIC_API_KEY")
78
+
79
+ if not anthropic_api_key:
80
+ raise ValueError("ANTHROPIC_API_KEY environment variable is required")
81
+
82
+ self.llm = LLM(
83
+ model="claude-3-haiku-20240307",
84
+ api_key=anthropic_api_key,
85
+ temperature=0,
86
+ )
87
+
88
+ @agent
89
+ def document_analyst(self) -> Agent:
90
+ return Agent(
91
+ config=self.agents_config['document_analyst'],
92
+ verbose=True,
93
+ tools=[landing_ai_document_analysis],
94
+ llm=self.llm,
95
+ )
96
+
97
+ @task
98
+ def document_analysis(self) -> Task:
99
+ return Task(
100
+ config=self.tasks_config['document_analysis'],
101
+ )
102
+
103
+ @crew
104
+ def crew(self) -> Crew:
105
+ """Creates the DocProcessing crew"""
106
+ return Crew(
107
+ agents=self.agents, # Automatically created by the @agent decorator
108
+ tasks=self.tasks, # Automatically created by the @task decorator
109
+ process=Process.sequential,
110
+ verbose=True,
111
+ )
main.py ADDED
@@ -0,0 +1,247 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # #!/usr/bin/env python
2
+ # import sys
3
+ # import os
4
+ # import warnings
5
+ # from crew import DocProcessing
6
+
7
+ # warnings.filterwarnings("ignore", category=SyntaxWarning, module="pysbd")
8
+
9
+ # def determine_file_type(file_path):
10
+ # """
11
+ # Determine the file type based on the file extension.
12
+
13
+ # Args:
14
+ # file_path (str): Path to the file
15
+
16
+ # Returns:
17
+ # str: 'pdf' if the file is a PDF, 'image' otherwise
18
+ # """
19
+ # _, ext = os.path.splitext(file_path)
20
+ # if ext.lower() == '.pdf':
21
+ # return 'pdf'
22
+ # return 'image'
23
+
24
+ # def run():
25
+ # """
26
+ # Run the crew with file paths received from command line arguments.
27
+ # """
28
+ # # Get file paths from command line arguments
29
+ # file_paths = sys.argv[1:] if len(sys.argv) > 1 else []
30
+
31
+ # if not file_paths:
32
+ # print("No file paths provided. Usage: python main.py <file_path1> <file_path2> ...")
33
+ # return
34
+
35
+ # # Process the first file (you can modify this to handle multiple files if needed)
36
+ # file_path = file_paths[0]
37
+ # file_type = determine_file_type(file_path)
38
+
39
+ # print(f"Processing file: {file_path} (type: {file_type})")
40
+
41
+ # # Prepare inputs for the CrewAI
42
+ # inputs = {
43
+ # "file_path": file_path,
44
+ # "file_type": file_type,
45
+ # }
46
+
47
+ # try:
48
+ # # Pass the inputs to the crew kickoff method
49
+ # result = DocProcessing().crew().kickoff(inputs=inputs)
50
+ # return result
51
+ # except Exception as e:
52
+ # error_msg = f"An error occurred while running the crew: {e}"
53
+ # print(error_msg)
54
+ # raise Exception(error_msg)
55
+
56
+ # if __name__ == "__main__":
57
+ # run()
58
+
59
+
60
+
61
+ #!/usr/bin/env python
62
+ import os
63
+ import tempfile
64
+ import gradio as gr
65
+ import warnings
66
+ from crew import DocProcessing
67
+
68
+ warnings.filterwarnings("ignore", category=SyntaxWarning, module="pysbd")
69
+
70
+ def determine_file_type(file_path):
71
+ """
72
+ Determine the file type based on the file extension.
73
+
74
+ Args:
75
+ file_path (str): Path to the file
76
+
77
+ Returns:
78
+ str: 'pdf' if the file is a PDF, 'image' otherwise
79
+ """
80
+ _, ext = os.path.splitext(file_path)
81
+ if ext.lower() == '.pdf':
82
+ return 'pdf'
83
+ return 'image'
84
+
85
+ def process_document(file, anthropic_api_key, landing_ai_api_key):
86
+ """
87
+ Process the uploaded document using CrewAI.
88
+
89
+ Args:
90
+ file: Uploaded file from Gradio
91
+ anthropic_api_key (str): Anthropic API key
92
+ landing_ai_api_key (str): LandingAI API key
93
+
94
+ Returns:
95
+ str: Processing results or error message
96
+ """
97
+ try:
98
+ # Validate inputs
99
+ if file is None:
100
+ return "❌ Please upload a file first."
101
+
102
+ if not anthropic_api_key.strip():
103
+ return "❌ Please provide your Anthropic API key."
104
+
105
+ if not landing_ai_api_key.strip():
106
+ return "❌ Please provide your LandingAI API key."
107
+
108
+ # Set environment variables securely for this session
109
+ os.environ["ANTHROPIC_API_KEY"] = anthropic_api_key.strip()
110
+ os.environ["LANDING_AI_API_KEY"] = landing_ai_api_key.strip()
111
+
112
+ # Get file path and determine type
113
+ file_path = file.name
114
+ file_type = determine_file_type(file_path)
115
+
116
+ print(f"Processing file: {file_path} (type: {file_type})")
117
+
118
+ # Prepare inputs for CrewAI
119
+ inputs = {
120
+ "file_path": file_path,
121
+ "file_type": file_type,
122
+ }
123
+
124
+ # Process with CrewAI
125
+ result = DocProcessing().crew().kickoff(inputs=inputs)
126
+
127
+ # Clean up environment variables for security
128
+ if "ANTHROPIC_API_KEY" in os.environ:
129
+ del os.environ["ANTHROPIC_API_KEY"]
130
+ if "LANDING_AI_API_KEY" in os.environ:
131
+ del os.environ["LANDING_AI_API_KEY"]
132
+
133
+ return f"✅ **Processing Complete!**\n\n{result}"
134
+
135
+ except Exception as e:
136
+ # Clean up environment variables even on error
137
+ if "ANTHROPIC_API_KEY" in os.environ:
138
+ del os.environ["ANTHROPIC_API_KEY"]
139
+ if "LANDING_AI_API_KEY" in os.environ:
140
+ del os.environ["LANDING_AI_API_KEY"]
141
+
142
+ error_msg = f"❌ **Error occurred:** {str(e)}"
143
+ print(error_msg)
144
+ return error_msg
145
+
146
+ # Create Gradio interface
147
+ def create_interface():
148
+ """Create and return the Gradio interface."""
149
+
150
+ with gr.Blocks(
151
+ title="Document Analysis with CrewAI",
152
+ theme=gr.themes.Soft(),
153
+ css="""
154
+ .container {
155
+ max-width: 800px;
156
+ margin: auto;
157
+ }
158
+ .header {
159
+ text-align: center;
160
+ margin-bottom: 30px;
161
+ }
162
+ .api-section {
163
+ background-color: #f8f9fa;
164
+ padding: 20px;
165
+ border-radius: 10px;
166
+ margin-bottom: 20px;
167
+ }
168
+ """
169
+ ) as demo:
170
+
171
+ gr.HTML("""
172
+ <div class="header">
173
+ <h1>🤖 Document Analysis</h1>
174
+ <p>Upload your documents for intelligent analysis using AI agents</p>
175
+ </div>
176
+ """)
177
+
178
+ with gr.Row():
179
+ with gr.Column():
180
+ # API Keys Section
181
+ gr.HTML("<div class='api-section'>")
182
+ gr.Markdown("### 🔑 API Keys")
183
+ gr.Markdown("Enter your API keys below. They are used securely and not stored.")
184
+
185
+ anthropic_key = gr.Textbox(
186
+ label="Anthropic API Key",
187
+ placeholder="Enter your Anthropic API key...",
188
+ type="password",
189
+ info="Get your key from: https://console.anthropic.com/"
190
+ )
191
+
192
+ landing_ai_key = gr.Textbox(
193
+ label="LandingAI API Key",
194
+ placeholder="Enter your LandingAI API key...",
195
+ type="password",
196
+ info="Get your key from: https://landing.ai/"
197
+ )
198
+ gr.HTML("</div>")
199
+
200
+ # File Upload Section
201
+ gr.Markdown("### 📄 Upload Document")
202
+ file_input = gr.File(
203
+ label="Select your document (.pdf, .png, .jpg, .jpeg, .bmp, .tiff)",
204
+ file_types=[".pdf", ".png", ".jpg", ".jpeg", ".bmp", ".tiff"],
205
+ file_count="single"
206
+ )
207
+
208
+ # Process Button
209
+ process_btn = gr.Button(
210
+ "🚀 Analyze Document",
211
+ variant="primary",
212
+ size="lg"
213
+ )
214
+
215
+ with gr.Column():
216
+ # Results Section
217
+ gr.Markdown("### 📊 Analysis Results")
218
+ output = gr.Textbox(
219
+ label="Results",
220
+ placeholder="Upload a document and click 'Analyze Document' to see results here...",
221
+ lines=20,
222
+ max_lines=30,
223
+ show_copy_button=True
224
+ )
225
+
226
+ # Examples section
227
+
228
+
229
+ # Set up the event handler
230
+ process_btn.click(
231
+ fn=process_document,
232
+ inputs=[file_input, anthropic_key, landing_ai_key],
233
+ outputs=output,
234
+ show_progress=True
235
+ )
236
+
237
+ return demo
238
+
239
+ # Launch the application
240
+ if __name__ == "__main__":
241
+ demo = create_interface()
242
+ demo.launch(
243
+ server_name="0.0.0.0", # Important for HuggingFace deployment
244
+ server_port=7860, # Default port for HuggingFace
245
+ share=False,
246
+ show_error=True
247
+ )
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ gradio
2
+ crewai
tools/custom_tool.py ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # import os
2
+ # import requests
3
+ # from crewai.tools import tool
4
+ # from dotenv import load_dotenv
5
+
6
+ # # Load environment variables
7
+ # load_dotenv()
8
+
9
+ # @tool("LandingAI Document Analysis")
10
+ # def landing_ai_document_analysis(file_path: str, file_type: str = "image") -> str:
11
+ # """
12
+ # Analyze images or PDFs using LandingAI's document analysis API.
13
+
14
+ # Args:
15
+ # file_path (str): Path to the image or PDF file to analyze
16
+ # file_type (str): Type of file, either "image" or "pdf"
17
+
18
+ # Returns:
19
+ # str: Analysis results from the API
20
+ # """
21
+ # # Get API key from environment variable
22
+ # api_key = os.getenv("LANDING_AI_API_KEY")
23
+
24
+ # # API endpoint
25
+ # url = "https://api.va.landing.ai/v1/tools/agentic-document-analysis"
26
+
27
+ # # Prepare the file for upload based on file_type
28
+ # with open(file_path, "rb") as file_obj:
29
+ # if file_type.lower() == "pdf":
30
+ # files = {"pdf": file_obj}
31
+ # else:
32
+ # files = {"image": file_obj}
33
+
34
+ # # Prepare headers with authentication
35
+ # headers = {"Authorization": f"Basic {api_key}"}
36
+
37
+
38
+ # # Make the API request
39
+ # response = requests.post(url, files=files, headers=headers)
40
+
41
+ # return response.json()
42
+
43
+ import os
44
+ import requests
45
+ from crewai.tools import tool
46
+
47
+ @tool("LandingAI Document Analysis")
48
+ def landing_ai_document_analysis(file_path: str, file_type: str = "image") -> str:
49
+ """
50
+ Analyze images or PDFs using LandingAI's document analysis API.
51
+
52
+ Args:
53
+ file_path (str): Path to the image or PDF file to analyze
54
+ file_type (str): Type of file, either "image" or "pdf"
55
+
56
+ Returns:
57
+ str: Analysis results from the API
58
+ """
59
+ # Get API key from environment variable
60
+ api_key = os.getenv("LANDING_AI_API_KEY")
61
+
62
+ if not api_key:
63
+ return "Error: LANDING_AI_API_KEY environment variable is not set"
64
+
65
+ # API endpoint
66
+ url = "https://api.va.landing.ai/v1/tools/agentic-document-analysis"
67
+
68
+ try:
69
+ # Prepare the file for upload based on file_type
70
+ with open(file_path, "rb") as file_obj:
71
+ if file_type.lower() == "pdf":
72
+ files = {"pdf": file_obj}
73
+ else:
74
+ files = {"image": file_obj}
75
+
76
+ # Prepare headers with authentication
77
+ headers = {"Authorization": f"Basic {api_key}"}
78
+
79
+ # Make the API request
80
+ response = requests.post(url, files=files, headers=headers)
81
+
82
+ # Check if request was successful
83
+ if response.status_code == 200:
84
+ return response.json()
85
+ else:
86
+ return f"API Error: {response.status_code} - {response.text}"
87
+
88
+ except FileNotFoundError:
89
+ return f"Error: File not found at path: {file_path}"
90
+ except Exception as e:
91
+ return f"Error processing file: {str(e)}"