Skip to content

Commit f7e1dfd

Browse files
committed
refactor: ♻️ general refactoring
1 parent 2bba4fb commit f7e1dfd

3 files changed

Lines changed: 73 additions & 71 deletions

File tree

src/file_manipulator.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import os
22
from src.filler import Filler
33
from src.llm import LLM
4-
from commonforms import prepare_form
4+
from commonforms import prepare_form
5+
56

67
class FileManipulator:
78
def __init__(self):
@@ -13,8 +14,8 @@ def create_template(self, pdf_path: str):
1314
By using commonforms, we create an editable .pdf template and we store it.
1415
"""
1516
template_path = pdf_path[:-4] + "_template.pdf"
16-
prepare_form(pdf_path, template_path)
17-
return template_path
17+
prepare_form(pdf_path, template_path)
18+
return template_path
1819

1920
def fill_form(self, user_input: str, fields: list, pdf_form_path: str):
2021
"""
@@ -23,28 +24,24 @@ def fill_form(self, user_input: str, fields: list, pdf_form_path: str):
2324
"""
2425
print("[1] Received request from frontend.")
2526
print(f"[2] PDF template path: {pdf_form_path}")
26-
27+
2728
if not os.path.exists(pdf_form_path):
2829
print(f"Error: PDF template not found at {pdf_form_path}")
29-
return None # Or raise an exception
30+
return None # Or raise an exception
3031

3132
print("[3] Starting extraction and PDF filling process...")
3233
try:
3334
self.llm._target_fields = fields
3435
self.llm._transcript_text = user_input
35-
output_name = self.filler.fill_form(
36-
pdf_form=pdf_form_path,
37-
llm=self.llm
38-
)
39-
36+
output_name = self.filler.fill_form(pdf_form=pdf_form_path, llm=self.llm)
37+
4038
print("\n----------------------------------")
41-
print(f"✅ Process Complete.")
39+
print("✅ Process Complete.")
4240
print(f"Output saved to: {output_name}")
43-
41+
4442
return output_name
45-
43+
4644
except Exception as e:
4745
print(f"An error occurred during PDF generation: {e}")
4846
# Re-raise the exception so the frontend can handle it
4947
raise e
50-

src/filler.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,48 +3,50 @@
33
from datetime import datetime
44

55

6-
class Filler():
6+
class Filler:
77
def __init__(self):
88
pass
99

10-
def fill_form(self, pdf_form: str, llm : LLM):
10+
def fill_form(self, pdf_form: str, llm: LLM):
1111
"""
1212
Fill a PDF form with values from user_input using LLM.
1313
Fields are filled in the visual order (top-to-bottom, left-to-right).
1414
"""
15-
output_pdf = pdf_form[:-4] + "_" + datetime.now().strftime('%Y%m%d_%H%M%S') + "_filled.pdf"
16-
17-
# Generate dictionary of answers from your original function
15+
output_pdf = (
16+
pdf_form[:-4]
17+
+ "_"
18+
+ datetime.now().strftime("%Y%m%d_%H%M%S")
19+
+ "_filled.pdf"
20+
)
21+
22+
# Generate dictionary of answers from your original function
1823
t2j = llm.main_loop()
1924
textbox_answers = t2j.get_data() # This is a dictionary
2025

2126
answers_list = list(textbox_answers.values())
2227

23-
# Read PDF
28+
# Read PDF
2429
pdf = PdfReader(pdf_form)
2530

26-
# Loop through pages
31+
# Loop through pages
2732
for page in pdf.pages:
2833
if page.Annots:
2934
sorted_annots = sorted(
30-
page.Annots,
31-
key=lambda a: (-float(a.Rect[1]), float(a.Rect[0]))
35+
page.Annots, key=lambda a: (-float(a.Rect[1]), float(a.Rect[0]))
3236
)
3337

3438
i = 0
3539
for annot in sorted_annots:
36-
if annot.Subtype == '/Widget' and annot.T:
37-
field_name = annot.T[1:-1]
38-
40+
if annot.Subtype == "/Widget" and annot.T:
3941
if i < len(answers_list):
40-
annot.V = f'{answers_list[i]}'
42+
annot.V = f"{answers_list[i]}"
4143
annot.AP = None
4244
i += 1
4345
else:
4446
# Stop if we run out of answers
45-
break
47+
break
4648

4749
PdfWriter().write(output_pdf, pdf)
48-
50+
4951
# Your main.py expects this function to return the path
5052
return output_pdf

src/llm.py

Lines changed: 45 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,31 @@
22
import os
33
import requests
44

5-
class LLM():
5+
6+
class LLM:
67
def __init__(self, transcript_text=None, target_fields=None, json=None):
78
if json is None:
89
json = {}
9-
self._transcript_text = transcript_text # str
10-
self._target_fields = target_fields # List, contains the template field.
11-
self._json = json # dictionary
12-
10+
self._transcript_text = transcript_text # str
11+
self._target_fields = target_fields # List, contains the template field.
12+
self._json = json # dictionary
13+
1314
def type_check_all(self):
14-
if type(self._transcript_text) != str:
15-
raise TypeError(f"ERROR in LLM() attributes ->\
16-
Transcript must be text. Input:\n\ttranscript_text: {self._transcript_text}")
17-
elif type(self._target_fields) != list:
18-
raise TypeError(f"ERROR in LLM() attributes ->\
19-
Target fields must be a list. Input:\n\ttarget_fields: {self._target_fields}")
20-
21-
15+
if type(self._transcript_text) is not str:
16+
raise TypeError(
17+
f"ERROR in LLM() attributes ->\
18+
Transcript must be text. Input:\n\ttranscript_text: {self._transcript_text}"
19+
)
20+
elif type(self._target_fields) is not list:
21+
raise TypeError(
22+
f"ERROR in LLM() attributes ->\
23+
Target fields must be a list. Input:\n\ttarget_fields: {self._target_fields}"
24+
)
25+
2226
def build_prompt(self, current_field):
23-
"""
24-
This method is in charge of the prompt engineering. It creates a specific prompt for each target field.
25-
@params: current_field -> represents the current element of the json that is being prompted.
27+
"""
28+
This method is in charge of the prompt engineering. It creates a specific prompt for each target field.
29+
@params: current_field -> represents the current element of the json that is being prompted.
2630
"""
2731
prompt = f"""
2832
SYSTEM PROMPT:
@@ -52,7 +56,7 @@ def main_loop(self):
5256
payload = {
5357
"model": "mistral",
5458
"prompt": prompt,
55-
"stream": False # don't really know why --> look into this later.
59+
"stream": False, # don't really know why --> look into this later.
5660
}
5761

5862
try:
@@ -68,11 +72,10 @@ def main_loop(self):
6872

6973
# parse response
7074
json_data = response.json()
71-
parsed_response = json_data['response']
75+
parsed_response = json_data["response"]
7276
# print(parsed_response)
7377
self.add_response_to_json(field, parsed_response)
7478

75-
7679
print("----------------------------------")
7780
print("\t[LOG] Resulting JSON created from the input text:")
7881
print(json.dumps(self._json, indent=2))
@@ -81,52 +84,52 @@ def main_loop(self):
8184
return self
8285

8386
def add_response_to_json(self, field, value):
84-
"""
85-
this method adds the following value under the specified field,
86-
or under a new field if the field doesn't exist, to the json dict
8787
"""
88-
value = value.strip().replace('"', '')
88+
this method adds the following value under the specified field,
89+
or under a new field if the field doesn't exist, to the json dict
90+
"""
91+
value = value.strip().replace('"', "")
8992
parsed_value = None
90-
plural = False
91-
93+
9294
if value != "-1":
93-
parsed_value = value
94-
95+
parsed_value = value
96+
9597
if ";" in value:
9698
parsed_value = self.handle_plural_values(value)
97-
plural = True
98-
9999

100100
if field in self._json.keys():
101101
self._json[field].append(parsed_value)
102-
else:
102+
else:
103103
self._json[field] = parsed_value
104-
104+
105105
return
106106

107107
def handle_plural_values(self, plural_value):
108-
"""
109-
This method handles plural values.
110-
Takes in strings of the form 'value1; value2; value3; ...; valueN'
111-
returns a list with the respective values -> [value1, value2, value3, ..., valueN]
108+
"""
109+
This method handles plural values.
110+
Takes in strings of the form 'value1; value2; value3; ...; valueN'
111+
returns a list with the respective values -> [value1, value2, value3, ..., valueN]
112112
"""
113113
if ";" not in plural_value:
114-
raise ValueError(f"Value is not plural, doesn't have ; separator, Value: {plural_value}")
115-
116-
print(f"\t[LOG]: Formating plural values for JSON, [For input {plural_value}]...")
114+
raise ValueError(
115+
f"Value is not plural, doesn't have ; separator, Value: {plural_value}"
116+
)
117+
118+
print(
119+
f"\t[LOG]: Formating plural values for JSON, [For input {plural_value}]..."
120+
)
117121
values = plural_value.split(";")
118-
122+
119123
# Remove trailing leading whitespace
120124
for i in range(len(values)):
121-
current = i+1
125+
current = i + 1
122126
if current < len(values):
123127
clean_value = values[current].lstrip()
124128
values[current] = clean_value
125129

126130
print(f"\t[LOG]: Resulting formatted list of values: {values}")
127-
131+
128132
return values
129-
130133

131134
def get_data(self):
132135
return self._json

0 commit comments

Comments
 (0)