Spaces:
Runtime error
Runtime error
| import os | |
| from datasets.filesystems import S3FileSystem | |
| import s3fs | |
| import boto3 | |
| from pdf2image import convert_from_path | |
| import csv | |
| from PIL import Image | |
| import gradio as gr | |
| import datetime | |
| # AWS and S3 Initialization with environment variables | |
| aws_access_key_id = os.getenv('AWS_ACCESS_KEY') | |
| aws_secret_access_key = os.getenv('AWS_SECRET_KEY') | |
| region_name = os.getenv('AWS_REGION') | |
| s3_bucket = os.getenv('AWS_BUCKET') | |
| # Properly initialize s3fs with environment variables | |
| s3 = s3fs.S3FileSystem( | |
| key=os.getenv('AWS_ACCESS_KEY'), | |
| secret=os.getenv('AWS_SECRET_KEY'), | |
| client_kwargs={'region_name': os.getenv('AWS_REGION')} | |
| ) | |
| # textract_client = boto3.client('textract', region_name=region_name) | |
| textract_client = boto3.client('textract', aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, region_name=region_name) | |
| def upload_file_to_s3(file_path, bucket, object_name=None): | |
| if object_name is None: | |
| object_name = os.path.basename(file_path) | |
| try: | |
| s3_path = f"{bucket}/{object_name}" | |
| s3.upload(file_path, s3_path) | |
| return object_name | |
| except FileNotFoundError: | |
| print("The file was not found") | |
| return None | |
| def process_image(file_path, s3_bucket, textract_client): | |
| s3_object_key = upload_file_to_s3(file_path, s3_bucket) | |
| if not s3_object_key: | |
| return None | |
| response = textract_client.analyze_document( | |
| Document={'S3Object': {'Bucket': s3_bucket, 'Name': s3_object_key}}, | |
| FeatureTypes=["TABLES"] | |
| ) | |
| return response | |
| def generate_table_csv(tables, blocks_map, csv_output_path): | |
| # Open the CSV file in append mode to add content without overwriting existing data | |
| with open(csv_output_path, 'a', newline='') as csvfile: | |
| writer = csv.writer(csvfile) | |
| for table in tables: | |
| rows = get_rows_columns_map(table, blocks_map) | |
| for row_index, cols in rows.items(): | |
| row = [] | |
| for col_index in range(1, max(cols.keys()) + 1): | |
| row.append(cols.get(col_index, "")) | |
| writer.writerow(row) | |
| def get_rows_columns_map(table_result, blocks_map): | |
| rows = {} | |
| for relationship in table_result['Relationships']: | |
| if relationship['Type'] == 'CHILD': | |
| for child_id in relationship['Ids']: | |
| cell = blocks_map[child_id] | |
| if 'RowIndex' in cell and 'ColumnIndex' in cell: | |
| row_index = cell['RowIndex'] | |
| col_index = cell['ColumnIndex'] | |
| if row_index not in rows: | |
| rows[row_index] = {} | |
| rows[row_index][col_index] = get_text(cell, blocks_map) | |
| return rows | |
| def get_text(result, blocks_map): | |
| text = '' | |
| if 'Relationships' in result: | |
| for relationship in result['Relationships']: | |
| if relationship['Type'] == 'CHILD': | |
| for child_id in relationship['Ids']: | |
| word = blocks_map[child_id] | |
| if word['BlockType'] == 'WORD': | |
| text += word['Text'] + ' ' | |
| if word['BlockType'] == 'SELECTION_ELEMENT': | |
| if word['SelectionStatus'] == 'SELECTED': | |
| text += 'X ' | |
| return text.strip() | |
| def process_file_and_generate_csv(file_path): | |
| # The file_path is directly usable; no need to check for attributes or methods | |
| timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") | |
| csv_output_path = f"/tmp/output_{timestamp}.csv" | |
| if file_path.lower().endswith(('.png', '.jpg', '.jpeg')): | |
| images = [Image.open(file_path)] | |
| else: | |
| # Convert PDF or other supported formats to images | |
| images = convert_from_path(file_path) | |
| for i, image in enumerate(images): | |
| image_path = f"/tmp/image_{i}.jpg" | |
| image.save(image_path, 'JPEG') | |
| response = process_image(image_path, s3_bucket, textract_client) | |
| if response: | |
| blocks = response['Blocks'] | |
| blocks_map = {block['Id']: block for block in blocks} | |
| tables = [block for block in blocks if block['BlockType'] == "TABLE"] | |
| generate_table_csv(tables, blocks_map, csv_output_path) | |
| # No need to remove the original file_path; Gradio handles temporary file cleanup | |
| # Return the CSV output path and a success message for Gradio to handle | |
| return csv_output_path, "Processing completed successfully!" | |
| # Gradio Interface | |
| iface = gr.Interface( | |
| fn=process_file_and_generate_csv, | |
| inputs=gr.File(label="Upload your file (PDF, PNG, JPG, TIFF)"), | |
| outputs=[gr.File(label="Download Generated CSV"), "text"], | |
| description="Upload a document to extract tables into a CSV file." | |
| ) | |
| if __name__ == "__main__": | |
| iface.launch() | |