marcosremar2 commited on
Commit
8d53d80
·
1 Parent(s): 18d7ae3

Simplified app to use in-memory storage instead of S3

Browse files
Files changed (2) hide show
  1. app.py +173 -0
  2. requirements.txt +4 -0
app.py ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from typing import Dict
3
+ import os
4
+ import base64
5
+ from magic_pdf.user_api import parse_union_pdf
6
+ from magic_pdf.rw import BaseReaderWriter
7
+ from loguru import logger
8
+ from io import BytesIO
9
+
10
+ class InMemoryReaderWriter(BaseReaderWriter):
11
+ """In-memory implementation of ReaderWriter that stores files in memory"""
12
+
13
+ def __init__(self):
14
+ self.storage = {} # Dictionary to store files in memory
15
+
16
+ def write(self, content, path, content_type=None):
17
+ """Write content to in-memory storage"""
18
+ self.storage[path] = content
19
+ return f"memory://{path}"
20
+
21
+ def read(self, path):
22
+ """Read content from in-memory storage"""
23
+ if path.startswith("memory://"):
24
+ path = path[9:] # Remove "memory://" prefix
25
+
26
+ if path in self.storage:
27
+ return self.storage[path]
28
+ else:
29
+ raise FileNotFoundError(f"File not found in memory storage: {path}")
30
+
31
+ def get_storage():
32
+ """Initialize in-memory storage"""
33
+ return InMemoryReaderWriter()
34
+
35
+ def inference(inputs: Dict):
36
+ """
37
+ Serverless API entry point
38
+ """
39
+ try:
40
+ # Validate input
41
+ if "pdf_bytes" not in inputs:
42
+ return {"status": "error", "message": "No PDF data provided"}
43
+
44
+ # Base64 decode PDF content
45
+ try:
46
+ pdf_bytes = base64.b64decode(inputs["pdf_bytes"])
47
+ except Exception as e:
48
+ return {"status": "error", "message": f"Invalid PDF data: {str(e)}"}
49
+
50
+ # Initialize in-memory writer
51
+ image_writer = get_storage()
52
+
53
+ # Prepare parameters
54
+ kwargs = {
55
+ "lang": inputs.get("lang", "zh"),
56
+ "layout_model": inputs.get("layout_model", True),
57
+ "formula_enable": inputs.get("formula_enable", True),
58
+ "table_enable": inputs.get("table_enable", True),
59
+ "input_model_is_empty": True
60
+ }
61
+
62
+ # Process using parse_union_pdf
63
+ result = parse_union_pdf(
64
+ pdf_bytes=pdf_bytes,
65
+ pdf_models=[], # Use built-in models
66
+ imageWriter=image_writer,
67
+ **kwargs
68
+ )
69
+
70
+ return {
71
+ "status": "success",
72
+ "data": result
73
+ }
74
+
75
+ except Exception as e:
76
+ logger.exception("Error processing PDF")
77
+ return {
78
+ "status": "error",
79
+ "message": str(e)
80
+ }
81
+
82
+ # Create Gradio interface
83
+ def process_pdf_ui(pdf_file, lang="zh", layout_model=True, formula_enable=True, table_enable=True):
84
+ if pdf_file is None:
85
+ return {"status": "error", "message": "No PDF file provided"}
86
+
87
+ # Convert uploaded file to base64
88
+ pdf_bytes = pdf_file
89
+ encoded_pdf = base64.b64encode(pdf_bytes).decode('utf-8')
90
+
91
+ # Call the inference function
92
+ result = inference({
93
+ "pdf_bytes": encoded_pdf,
94
+ "lang": lang,
95
+ "layout_model": layout_model,
96
+ "formula_enable": formula_enable,
97
+ "table_enable": table_enable
98
+ })
99
+
100
+ return result
101
+
102
+ # Create Gradio interface with API
103
+ with gr.Blocks() as demo:
104
+ gr.Markdown("# PDF Processing API")
105
+
106
+ with gr.Tab("UI Demo"):
107
+ with gr.Row():
108
+ with gr.Column():
109
+ pdf_input = gr.File(label="Upload PDF")
110
+ lang = gr.Dropdown(["zh", "en"], label="Language", value="zh")
111
+ layout_model = gr.Checkbox(label="Use Layout Model", value=True)
112
+ formula_enable = gr.Checkbox(label="Enable Formula Detection", value=True)
113
+ table_enable = gr.Checkbox(label="Enable Table Detection", value=True)
114
+ submit_btn = gr.Button("Process PDF")
115
+
116
+ with gr.Column():
117
+ output = gr.JSON(label="Result")
118
+
119
+ submit_btn.click(
120
+ fn=process_pdf_ui,
121
+ inputs=[pdf_input, lang, layout_model, formula_enable, table_enable],
122
+ outputs=output
123
+ )
124
+
125
+ with gr.Tab("API Documentation"):
126
+ gr.Markdown("""
127
+ ## API Usage
128
+
129
+ ### Endpoint
130
+ `POST https://marcosremar2-apimineru.hf.space/api/predict`
131
+
132
+ ### Request Format
133
+ ```json
134
+ {
135
+ "pdf_bytes": "base64 encoded PDF content",
136
+ "lang": "zh", // Optional, default "zh"
137
+ "layout_model": true, // Optional, default true
138
+ "formula_enable": true, // Optional, default true
139
+ "table_enable": true // Optional, default true
140
+ }
141
+ ```
142
+
143
+ ### Python Example
144
+ ```python
145
+ from huggingface_hub import InferenceClient
146
+ import base64
147
+
148
+ def process_pdf(pdf_path: str, hf_token: str):
149
+ # Create client
150
+ client = InferenceClient(
151
+ model="marcosremar2/apimineru",
152
+ token=hf_token
153
+ )
154
+
155
+ # Read and encode PDF
156
+ with open(pdf_path, 'rb') as f:
157
+ pdf_bytes = base64.b64encode(f.read()).decode()
158
+
159
+ # Send request
160
+ response = client.post(json={
161
+ "pdf_bytes": pdf_bytes,
162
+ "lang": "zh",
163
+ "layout_model": True,
164
+ "formula_enable": True,
165
+ "table_enable": True
166
+ })
167
+
168
+ return response
169
+ ```
170
+ """)
171
+
172
+ # This exposes both the UI and API endpoints
173
+ demo.queue().launch()
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ gradio>=3.50.2
2
+ magic-pdf>=1.3.8
3
+ loguru
4
+ huggingface_hub