ChintanSatva commited on
Commit
5c093fd
·
verified ·
1 Parent(s): c93633a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +109 -13
app.py CHANGED
@@ -4,13 +4,19 @@ import base64
4
  from typing import List
5
  import tempfile
6
  import os
 
 
7
  from fastapi.responses import JSONResponse
8
 
 
 
 
 
9
  app = FastAPI(title="PDF to Images API", description="API to convert PDF files to images for accounting automation")
10
 
11
  @app.post("/pdf_to_images", response_model=List[str])
12
  async def pdf_to_images(
13
- file: UploadFile = File(...),
14
  dpi: int = Query(200, description="DPI for image conversion")
15
  ):
16
  # Validate file type
@@ -18,31 +24,121 @@ async def pdf_to_images(
18
  raise HTTPException(status_code=400, detail="Only PDF files are allowed")
19
 
20
  # Read the PDF content into memory
21
- contents = await file.read()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
  try:
24
  # Create a temporary directory to store the images
25
  with tempfile.TemporaryDirectory() as temp_dir:
 
 
26
  # Convert PDF bytes to image paths (saves to disk to avoid memory issues)
27
  image_paths = convert_from_bytes(
28
- contents,
29
- dpi=dpi,
30
- output_folder=temp_dir,
31
- fmt="png",
32
  paths_only=True
33
  )
34
 
 
 
35
  # Convert images to base64 strings from files
36
  image_b64_list = []
37
- for path in image_paths:
38
- with open(path, "rb") as img_file:
39
- b64_string = base64.b64encode(img_file.read()).decode("utf-8")
40
- image_b64_list.append(b64_string)
41
-
42
- return image_b64_list
 
 
 
 
 
 
 
 
 
43
  except Exception as e:
 
44
  raise HTTPException(status_code=500, detail=f"Error processing PDF: {str(e)}")
45
 
46
  @app.get("/")
47
  async def root():
48
- return {"message": "Welcome to the PDF to Images API. Use POST /pdf_to_images to convert a PDF to images."}
 
 
 
 
 
 
 
 
 
 
 
 
4
  from typing import List
5
  import tempfile
6
  import os
7
+ import io
8
+ import logging
9
  from fastapi.responses import JSONResponse
10
 
11
+ # Configure logging
12
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
13
+ logger = logging.getLogger(__name__)
14
+
15
  app = FastAPI(title="PDF to Images API", description="API to convert PDF files to images for accounting automation")
16
 
17
  @app.post("/pdf_to_images", response_model=List[str])
18
  async def pdf_to_images(
19
+ file: UploadFile = File(...),
20
  dpi: int = Query(200, description="DPI for image conversion")
21
  ):
22
  # Validate file type
 
24
  raise HTTPException(status_code=400, detail="Only PDF files are allowed")
25
 
26
  # Read the PDF content into memory
27
+ try:
28
+ contents = await file.read()
29
+ logger.info(f"Successfully read PDF file: {file.filename}, size: {len(contents)} bytes")
30
+ except Exception as e:
31
+ logger.error(f"Failed to read PDF file {file.filename}: {str(e)}")
32
+ raise HTTPException(status_code=500, detail=f"Failed to read PDF file: {str(e)}")
33
+
34
+ try:
35
+ # Convert PDF bytes to PIL Image objects directly (memory efficient)
36
+ logger.info(f"Starting PDF to images conversion for {file.filename} with DPI={dpi}")
37
+
38
+ # Convert PDF bytes to images - this returns PIL Image objects
39
+ images = convert_from_bytes(
40
+ contents,
41
+ dpi=dpi,
42
+ fmt='PNG' # Specify format explicitly
43
+ )
44
+
45
+ logger.info(f"Successfully converted PDF to {len(images)} images")
46
+
47
+ # Convert PIL Images to base64 strings
48
+ image_b64_list = []
49
+ for i, image in enumerate(images):
50
+ try:
51
+ # Convert PIL Image to bytes
52
+ img_byte_arr = io.BytesIO()
53
+ image.save(img_byte_arr, format='PNG')
54
+ img_byte_arr.seek(0)
55
+
56
+ # Encode to base64
57
+ b64_string = base64.b64encode(img_byte_arr.getvalue()).decode("utf-8")
58
+ image_b64_list.append(b64_string)
59
+
60
+ logger.info(f"Processed image {i+1}/{len(images)} from {file.filename}")
61
+
62
+ except Exception as e:
63
+ logger.error(f"Failed to process image {i+1} from {file.filename}: {str(e)}")
64
+ raise HTTPException(status_code=500, detail=f"Error processing image {i+1}: {str(e)}")
65
+
66
+ logger.info(f"Successfully converted {file.filename} to {len(image_b64_list)} base64 images")
67
+ return image_b64_list
68
+
69
+ except Exception as e:
70
+ logger.error(f"Error processing PDF {file.filename}: {str(e)}")
71
+ raise HTTPException(status_code=500, detail=f"Error processing PDF: {str(e)}")
72
+
73
+ @app.post("/pdf_to_images_with_temp", response_model=List[str])
74
+ async def pdf_to_images_with_temp(
75
+ file: UploadFile = File(...),
76
+ dpi: int = Query(200, description="DPI for image conversion")
77
+ ):
78
+ """
79
+ Alternative endpoint that uses temporary files - useful for very large PDFs
80
+ to avoid memory issues
81
+ """
82
+ # Validate file type
83
+ if not file.filename.lower().endswith(".pdf"):
84
+ raise HTTPException(status_code=400, detail="Only PDF files are allowed")
85
+
86
+ # Read the PDF content into memory
87
+ try:
88
+ contents = await file.read()
89
+ logger.info(f"Successfully read PDF file: {file.filename}, size: {len(contents)} bytes")
90
+ except Exception as e:
91
+ logger.error(f"Failed to read PDF file {file.filename}: {str(e)}")
92
+ raise HTTPException(status_code=500, detail=f"Failed to read PDF file: {str(e)}")
93
 
94
  try:
95
  # Create a temporary directory to store the images
96
  with tempfile.TemporaryDirectory() as temp_dir:
97
+ logger.info(f"Created temporary directory: {temp_dir}")
98
+
99
  # Convert PDF bytes to image paths (saves to disk to avoid memory issues)
100
  image_paths = convert_from_bytes(
101
+ contents,
102
+ dpi=dpi,
103
+ output_folder=temp_dir,
104
+ fmt="png",
105
  paths_only=True
106
  )
107
 
108
+ logger.info(f"Successfully converted PDF to {len(image_paths)} image files")
109
+
110
  # Convert images to base64 strings from files
111
  image_b64_list = []
112
+ for i, path in enumerate(image_paths):
113
+ try:
114
+ with open(path, "rb") as img_file:
115
+ b64_string = base64.b64encode(img_file.read()).decode("utf-8")
116
+ image_b64_list.append(b64_string)
117
+
118
+ logger.info(f"Processed image file {i+1}/{len(image_paths)}: {os.path.basename(path)}")
119
+
120
+ except Exception as e:
121
+ logger.error(f"Failed to process image file {path}: {str(e)}")
122
+ raise HTTPException(status_code=500, detail=f"Error processing image file: {str(e)}")
123
+
124
+ logger.info(f"Successfully converted {file.filename} to {len(image_b64_list)} base64 images using temp files")
125
+ return image_b64_list
126
+
127
  except Exception as e:
128
+ logger.error(f"Error processing PDF {file.filename}: {str(e)}")
129
  raise HTTPException(status_code=500, detail=f"Error processing PDF: {str(e)}")
130
 
131
  @app.get("/")
132
  async def root():
133
+ return {
134
+ "message": "Welcome to the PDF to Images API",
135
+ "endpoints": {
136
+ "pdf_to_images": "Convert PDF to images (memory efficient)",
137
+ "pdf_to_images_with_temp": "Convert PDF to images using temporary files (for very large PDFs)"
138
+ },
139
+ "usage": "Use POST /pdf_to_images to convert a PDF to base64 encoded images"
140
+ }
141
+
142
+ @app.get("/health")
143
+ async def health_check():
144
+ return {"status": "healthy", "service": "PDF to Images API"}