AdityaAdaki commited on
Commit
9d1b3b9
·
1 Parent(s): 118480e

Initial commit

Browse files
Files changed (6) hide show
  1. .env +1 -0
  2. Dockerfile +7 -0
  3. app.py +71 -0
  4. fire.pdf +0 -0
  5. requirements.txt +4 -0
  6. templates/index.html +216 -0
.env ADDED
@@ -0,0 +1 @@
 
 
1
+ GEMINI_API_KEY=AIzaSyCtEVix5c3pv3wtt7JLUA0CWpmOCt2gBMw
Dockerfile ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ FROM python:3.9-slim
2
+ WORKDIR /code
3
+ COPY ./requirements.txt /code/requirements.txt
4
+ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
5
+ COPY . .
6
+ EXPOSE 7860
7
+ CMD ["python", "app.py"]
app.py ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, render_template
2
+ import google.generativeai as genai
3
+ import base64
4
+ import os
5
+ from dotenv import load_dotenv
6
+
7
+ # Initialize Flask app
8
+ app = Flask(__name__)
9
+
10
+ # Gemini API Configuration
11
+ genai.configure(api_key=os.getenv('GEMINI_API_KEY'))
12
+ model = genai.GenerativeModel("gemini-1.5-flash")
13
+
14
+ def process_certificate(image_path, cert_name):
15
+ """Process a single certificate and generate a response in structured HTML."""
16
+ with open(image_path, "rb") as image_file:
17
+ encoded_image = base64.b64encode(image_file.read()).decode("utf-8")
18
+
19
+ prompt = (
20
+ """Note: The current date is 12/12/2024 (12 December 2024). Process the following certificate:
21
+ - {cert_name}: (image attached)
22
+
23
+ For the certificate:
24
+ 1. Check the expiry date on the certificate. Use the current date (12 December 2024) as the reference point:
25
+ - If the expiry date is earlier than the current date (past date), mark the certificate as Invalid❌.
26
+ - If the expiry date is later than the current date (future date), mark the certificate as Valid✅.
27
+ - If no expiry date is found but there are signs of validity (e.g., government seals, authorized signatures, or proper right marks), mark the certificate as Valid✅.
28
+
29
+ 2. If neither the expiry date nor other validity signs are present, use semantic analysis of the certificate's content to determine its status:
30
+ - Mark the certificate as Valid✅ if the content supports its authenticity (e.g., trustworthy terms, verified names, or credible organizations).
31
+ - Mark the certificate as Invalid❌ if the content lacks any evidence of validity.
32
+
33
+ 3. Structure the results in a clear and properly formatted table with the following columns:
34
+ - *Field*: Field extracted from the certificate.
35
+ - *Value*: The corresponding value.
36
+
37
+ 4. Add a section indicating the certificate's overall validity status (Valid✅ or Invalid❌).
38
+
39
+ Return the entire result strictly within the '''html opening and '''html closing tags.
40
+ Ensure compatibility with rendering on a webpage.
41
+ """.format(cert_name=cert_name)
42
+ )
43
+
44
+ response = model.generate_content([
45
+ {'mime_type': 'image/jpeg', 'data': encoded_image}, prompt
46
+ ])
47
+
48
+ return response.text
49
+
50
+ @app.route("/", methods=["GET", "POST"])
51
+ def home():
52
+ if request.method == "POST":
53
+ cert_name = "Affiliation Certificate"
54
+
55
+ file = request.files.get("certificate")
56
+ if file and file.filename: # Check if a file was uploaded
57
+ os.makedirs("static/uploads", exist_ok=True)
58
+ image_path = os.path.join("static/uploads", file.filename)
59
+ file.save(image_path)
60
+
61
+ # Process the certificate
62
+ gemini_output = process_certificate(image_path, cert_name)
63
+
64
+ return render_template("index.html", gemini_output=gemini_output)
65
+
66
+ return render_template("index.html", error="Please upload a certificate.")
67
+
68
+ return render_template("index.html")
69
+
70
+ if __name__ == "__main__":
71
+ app.run(host='0.0.0.0', port=7860)
fire.pdf ADDED
Binary file (102 kB). View file
 
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ flask==2.0.1
2
+ google-generativeai
3
+ python-dotenv
4
+ Werkzeug==2.0.3
templates/index.html ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Certificate Validation</title>
7
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
9
+ <style>
10
+ body {
11
+ background: linear-gradient(135deg, #f5f7fa 0%, #e3e6f0 100%);
12
+ color: #2c3e50;
13
+ font-family: 'Poppins', sans-serif;
14
+ min-height: 100vh;
15
+ }
16
+
17
+ .container {
18
+ margin-top: 50px;
19
+ padding: 30px;
20
+ background: rgba(255, 255, 255, 0.95);
21
+ border-radius: 15px;
22
+ box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
23
+ border: 1px solid #e0e0e0;
24
+ }
25
+
26
+ h1 {
27
+ font-weight: 700;
28
+ text-align: center;
29
+ margin-bottom: 40px;
30
+ font-size: 2.5rem;
31
+ color: #1a365d;
32
+ }
33
+
34
+ .upload-container {
35
+ background: #f8fafc;
36
+ border-radius: 12px;
37
+ padding: 30px;
38
+ text-align: center;
39
+ border: 2px dashed #cbd5e0;
40
+ transition: all 0.3s ease;
41
+ }
42
+
43
+ .upload-container:hover {
44
+ border-color: #4a90e2;
45
+ transform: translateY(-3px);
46
+ }
47
+
48
+ .upload-icon {
49
+ font-size: 48px;
50
+ color: #4a90e2;
51
+ margin-bottom: 15px;
52
+ }
53
+
54
+ .form-control {
55
+ background: #ffffff;
56
+ border: 1px solid #e2e8f0;
57
+ border-radius: 8px;
58
+ color: #2d3748;
59
+ padding: 12px;
60
+ transition: all 0.3s ease;
61
+ }
62
+
63
+ .form-control:focus {
64
+ border-color: #4a90e2;
65
+ box-shadow: 0 0 0 3px rgba(74, 144, 226, 0.1);
66
+ }
67
+
68
+ .btn-primary {
69
+ background: linear-gradient(45deg, #4a90e2, #5a9ee6);
70
+ border: none;
71
+ border-radius: 8px;
72
+ padding: 12px 30px;
73
+ font-weight: 600;
74
+ letter-spacing: 0.5px;
75
+ box-shadow: 0 4px 12px rgba(74, 144, 226, 0.15);
76
+ transition: all 0.3s ease;
77
+ }
78
+
79
+ .btn-primary:hover {
80
+ transform: translateY(-2px);
81
+ box-shadow: 0 6px 15px rgba(74, 144, 226, 0.2);
82
+ background: linear-gradient(45deg, #5a9ee6, #4a90e2);
83
+ }
84
+
85
+ .table-wrapper {
86
+ margin-top: 40px;
87
+ background: #ffffff;
88
+ border-radius: 12px;
89
+ padding: 25px;
90
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
91
+ border: 1px solid #e0e0e0;
92
+ }
93
+
94
+ .table-wrapper h2 {
95
+ color: #1a365d;
96
+ font-weight: 600;
97
+ text-align: center;
98
+ margin-bottom: 25px;
99
+ font-size: 1.8rem;
100
+ }
101
+
102
+ table {
103
+ width: 100%;
104
+ border-collapse: separate;
105
+ border-spacing: 0 8px;
106
+ }
107
+
108
+ th {
109
+ background: #f8fafc;
110
+ color: #2d3748;
111
+ font-weight: 600;
112
+ text-transform: uppercase;
113
+ letter-spacing: 1px;
114
+ font-size: 0.9rem;
115
+ padding: 15px;
116
+ border-bottom: 2px solid #e2e8f0;
117
+ }
118
+
119
+ td {
120
+ background: #ffffff;
121
+ color: #2d3748;
122
+ padding: 15px;
123
+ border-bottom: 1px solid #e2e8f0;
124
+ }
125
+
126
+ tr:hover td {
127
+ background: #f8fafc;
128
+ transition: all 0.2s ease;
129
+ }
130
+
131
+ .alert-danger {
132
+ background: #fff5f5;
133
+ border: 1px solid #feb2b2;
134
+ color: #c53030;
135
+ border-radius: 8px;
136
+ padding: 15px;
137
+ }
138
+
139
+ .loading {
140
+ display: none;
141
+ text-align: center;
142
+ padding: 20px;
143
+ }
144
+
145
+ .loading-spinner {
146
+ width: 50px;
147
+ height: 50px;
148
+ border: 5px solid #e2e8f0;
149
+ border-top: 5px solid #4a90e2;
150
+ border-radius: 50%;
151
+ animation: spin 1s linear infinite;
152
+ }
153
+
154
+ @keyframes spin {
155
+ 0% { transform: rotate(0deg); }
156
+ 100% { transform: rotate(360deg); }
157
+ }
158
+
159
+ .file-name {
160
+ margin-top: 10px;
161
+ font-size: 0.9rem;
162
+ color: #718096;
163
+ }
164
+
165
+ h4 {
166
+ color: #2d3748;
167
+ font-weight: 600;
168
+ }
169
+ </style>
170
+ </head>
171
+ <body>
172
+ <div class="container">
173
+ <h1>Certificate Validation</h1>
174
+ <form method="POST" enctype="multipart/form-data" class="mb-4" id="upload-form">
175
+ <div class="upload-container mb-4">
176
+ <i class="fas fa-cloud-upload-alt upload-icon"></i>
177
+ <h4 class="mb-3">Upload Your Certificate</h4>
178
+ <input type="file" name="certificate" id="certificate" class="form-control" required accept="image/*,.pdf">
179
+ <div class="file-name" id="file-name"></div>
180
+ </div>
181
+ <button type="submit" class="btn btn-primary w-100">
182
+ <i class="fas fa-check-circle me-2"></i>Validate Certificate
183
+ </button>
184
+ </form>
185
+
186
+ <div class="loading" id="loading">
187
+ <div class="loading-spinner mb-3"></div>
188
+ <p>Processing your certificate...</p>
189
+ </div>
190
+
191
+ {% if gemini_output %}
192
+ <div class="table-wrapper">
193
+ <h2>Certificate Validation Results</h2>
194
+ {{ gemini_output | safe }}
195
+ </div>
196
+ {% elif error %}
197
+ <div class="alert alert-danger" role="alert">
198
+ <i class="fas fa-exclamation-circle me-2"></i>{{ error }}
199
+ </div>
200
+ {% endif %}
201
+ </div>
202
+
203
+ <script>
204
+ // Display file name when selected
205
+ document.getElementById('certificate').addEventListener('change', function(e) {
206
+ const fileName = e.target.files[0]?.name || 'No file selected';
207
+ document.getElementById('file-name').textContent = fileName;
208
+ });
209
+
210
+ // Show loading animation on form submit
211
+ document.getElementById('upload-form').addEventListener('submit', function() {
212
+ document.getElementById('loading').style.display = 'block';
213
+ });
214
+ </script>
215
+ </body>
216
+ </html>