rongo1 commited on
Commit
c609854
·
1 Parent(s): dae9b98
Files changed (5) hide show
  1. .gitignore +7 -1
  2. README.md +69 -10
  3. app.py +1 -1
  4. env.example +8 -1
  5. google.py → google_funcs.py +20 -0
.gitignore CHANGED
@@ -11,6 +11,10 @@ venv/
11
  # Environment variables
12
  .env
13
 
 
 
 
 
14
  # IDE
15
  .vscode/
16
  .idea/
@@ -39,4 +43,6 @@ Thumbs.db
39
 
40
  # Logs
41
  *.log
42
- business_card_extractor.log
 
 
 
11
  # Environment variables
12
  .env
13
 
14
+ # Google Drive authentication files
15
+ token.pickle
16
+ google_token_base64.txt
17
+
18
  # IDE
19
  .vscode/
20
  .idea/
 
43
 
44
  # Logs
45
  *.log
46
+ business_card_extractor.log
47
+
48
+ convert_token_to_base64.py
README.md CHANGED
@@ -11,25 +11,26 @@ pinned: false
11
 
12
  # Business Card Data Extractor 💼
13
 
14
- An AI-powered tool that extracts structured data from business card images using Google's Gemini AI. Upload business card images and get organized data exported to Excel files.
15
 
16
  ## Features
17
 
18
  - **Batch Processing**: Process multiple business cards at once (up to 5 per batch)
19
  - **AI Model Selection**: Choose between Gemini 2.5 Flash (fast) or Gemini 2.5 Pro (accuracy)
 
20
  - **Excel Export**: Get data in two formats:
21
  - Current session results
22
  - Cumulative database (appends across sessions)
23
  - **Smart Data Extraction**: Extracts name, company, title, emails, phones, address, website
24
- - **Image Storage**: Option to save uploaded images with timestamps
25
 
26
  ## How to Use
27
 
28
- 1. **Set API Key**: Add your Google Gemini API key as `Gemini_API` environment variable
29
  2. **Upload Images**: Select up to 5 business card images
30
  3. **Choose Model**: Select Gemini model (Flash for speed, Pro for accuracy)
31
  4. **Process**: Click "Extract Business Card Data"
32
- 5. **Download**: Get Excel files with extracted data
33
 
34
  ## Supported Data Fields
35
 
@@ -42,12 +43,70 @@ An AI-powered tool that extracts structured data from business card images using
42
  - **Website**: Company website URL
43
  - **Processing Info**: Timestamp, model used, filename
44
 
45
- ## Requirements
46
 
47
- - Google Gemini API key
48
- - Image formats: JPG, JPEG, PNG, WEBP
49
- - Maximum file size: 10MB per image
50
 
51
- ## API Usage
 
 
 
52
 
53
- This app uses Google's Gemini AI for intelligent text extraction from business card images. Batch processing reduces API costs by processing multiple cards in a single request.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
  # Business Card Data Extractor 💼
13
 
14
+ An AI-powered tool that extracts structured data from business card images using Google's Gemini AI. Upload business card images and get organized data exported to Excel files with automatic Google Drive storage.
15
 
16
  ## Features
17
 
18
  - **Batch Processing**: Process multiple business cards at once (up to 5 per batch)
19
  - **AI Model Selection**: Choose between Gemini 2.5 Flash (fast) or Gemini 2.5 Pro (accuracy)
20
+ - **Google Drive Storage**: Automatic upload to organized Drive folders
21
  - **Excel Export**: Get data in two formats:
22
  - Current session results
23
  - Cumulative database (appends across sessions)
24
  - **Smart Data Extraction**: Extracts name, company, title, emails, phones, address, website
25
+ - **Direct Links**: Access files directly through Google Drive URLs
26
 
27
  ## How to Use
28
 
29
+ 1. **Setup**: Complete the setup process below (one-time)
30
  2. **Upload Images**: Select up to 5 business card images
31
  3. **Choose Model**: Select Gemini model (Flash for speed, Pro for accuracy)
32
  4. **Process**: Click "Extract Business Card Data"
33
+ 5. **Access Files**: Download temporary copies or access permanent files via Google Drive links
34
 
35
  ## Supported Data Fields
36
 
 
43
  - **Website**: Company website URL
44
  - **Processing Info**: Timestamp, model used, filename
45
 
46
+ ## Setup Instructions
47
 
48
+ ### 1. Google Gemini API
49
+ - Get your API key from: https://aistudio.google.com/
50
+ - Set as environment variable: `Gemini_API`
51
 
52
+ ### 2. Google Drive API Setup
53
+ 1. **Create Google Cloud Project**:
54
+ - Go to https://console.cloud.google.com/
55
+ - Create a new project or select an existing one
56
 
57
+ 2. **Enable Google Drive API**:
58
+ - In the Google Cloud Console, go to "APIs & Services" > "Library"
59
+ - Search for "Google Drive API" and enable it
60
+
61
+ 3. **Create OAuth 2.0 Credentials**:
62
+ - Go to "APIs & Services" > "Credentials"
63
+ - Click "+ CREATE CREDENTIALS" > "OAuth client ID"
64
+ - Select "Desktop application"
65
+ - Download the JSON file
66
+ - Extract `client_id` and `client_secret` from the JSON
67
+
68
+ 4. **Set Environment Variables**:
69
+ ```bash
70
+ GOOGLE_CLIENT_ID=your_client_id_here
71
+ GOOGLE_CLIENT_SECRET=your_client_secret_here
72
+ ```
73
+
74
+ ### 3. Local Development Setup
75
+ 1. **Install Dependencies**:
76
+ ```bash
77
+ pip install -r requirements.txt
78
+ ```
79
+
80
+ 2. **Run Locally First**:
81
+ ```bash
82
+ python app.py
83
+ ```
84
+ - Complete the OAuth flow in your browser
85
+ - This creates `token.pickle` file
86
+
87
+ ### 4. Deployment Setup (Hugging Face Spaces, etc.)
88
+ 1. **Generate Token for Deployment**:
89
+ ```bash
90
+ python convert_token_to_base64.py
91
+ ```
92
+ - This converts `token.pickle` to a base64 string
93
+
94
+ 2. **Set Environment Variables** in your deployment platform:
95
+ ```bash
96
+ Gemini_API=your_gemini_api_key
97
+ GOOGLE_CLIENT_ID=your_google_client_id
98
+ GOOGLE_CLIENT_SECRET=your_google_client_secret
99
+ GOOGLE_TOKEN_BASE64=your_base64_encoded_token
100
+ ```
101
+
102
+ ## Google Drive Folders
103
+ - **📁 Exports**: https://drive.google.com/drive/folders/1k5iP4egzLrGJwnHkMhxt9bAkaCiieojO
104
+ - **🖼️ Images**: https://drive.google.com/drive/folders/1gd280IqcAzpAFTPeYsZjoBUOU9S7Zx3c
105
+
106
+ ## Technical Details
107
+
108
+ - **Image Formats**: JPG, JPEG, PNG, WEBP, BMP
109
+ - **Maximum File Size**: 10MB per image
110
+ - **Batch Processing**: Up to 5 cards per API call
111
+ - **Storage**: Automatic upload to Google Drive
112
+ - **Models**: Gemini 2.5 Flash (fast) / Pro (accurate)
app.py CHANGED
@@ -13,7 +13,7 @@ import sys
13
  import tempfile
14
 
15
  # Import Google Drive functionality
16
- from google import get_drive_service, upload_excel_to_exports_folder, upload_image_to_images_folder, list_files_in_folder
17
 
18
  # Configure logging
19
  logging.basicConfig(
 
13
  import tempfile
14
 
15
  # Import Google Drive functionality
16
+ from google_funcs import get_drive_service, upload_excel_to_exports_folder, upload_image_to_images_folder, list_files_in_folder
17
 
18
  # Configure logging
19
  logging.basicConfig(
env.example CHANGED
@@ -15,7 +15,14 @@ Gemini_API=your_gemini_api_key_here
15
  GOOGLE_CLIENT_ID=your_google_client_id_here
16
  GOOGLE_CLIENT_SECRET=your_google_client_secret_here
17
 
 
 
 
 
 
 
18
  # Examples:
19
  # Gemini_API=AIzaSyBxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
20
  # GOOGLE_CLIENT_ID=1234567890-abcdefghijklmnopqrstuvwxyz.apps.googleusercontent.com
21
- # GOOGLE_CLIENT_SECRET=GOCSPX-xxxxxxxxxxxxxxxxxxxxxxxx
 
 
15
  GOOGLE_CLIENT_ID=your_google_client_id_here
16
  GOOGLE_CLIENT_SECRET=your_google_client_secret_here
17
 
18
+ # Google Drive Token (Required for deployment environments)
19
+ # Generate this by running the app locally first, then use convert_token_to_base64.py
20
+ # For local development: Leave this empty (token.pickle will be created automatically)
21
+ # For deployment: Set this to the base64 encoded token string
22
+ GOOGLE_TOKEN_BASE64=your_base64_encoded_token_here
23
+
24
  # Examples:
25
  # Gemini_API=AIzaSyBxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
26
  # GOOGLE_CLIENT_ID=1234567890-abcdefghijklmnopqrstuvwxyz.apps.googleusercontent.com
27
+ # GOOGLE_CLIENT_SECRET=GOCSPX-xxxxxxxxxxxxxxxxxxxxxxxx
28
+ # GOOGLE_TOKEN_BASE64=gASVxwAAAAAAAAB9cQAoWBYAAABhY2Nlc3NfdG9rZW4... (very long string)
google.py → google_funcs.py RENAMED
@@ -1,5 +1,6 @@
1
  import os
2
  import pickle
 
3
  from google.auth.transport.requests import Request
4
  from google_auth_oauthlib.flow import InstalledAppFlow
5
  from googleapiclient.discovery import build
@@ -26,6 +27,22 @@ TOKEN_PICKLE_FILE = 'token.pickle'
26
  def get_drive_service():
27
  """Authenticates with Google and returns a Drive service object."""
28
  creds = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  # The file token.pickle stores the user's access and refresh tokens.
30
  if os.path.exists(TOKEN_PICKLE_FILE):
31
  with open(TOKEN_PICKLE_FILE, 'rb') as token:
@@ -34,11 +51,13 @@ def get_drive_service():
34
  # If there are no (valid) credentials available, let the user log in.
35
  if not creds or not creds.valid:
36
  if creds and creds.expired and creds.refresh_token:
 
37
  creds.refresh(Request())
38
  else:
39
  if not CLIENT_ID or not CLIENT_SECRET:
40
  raise ValueError("GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET environment variables are required")
41
 
 
42
  # Use client_config dictionary instead of a client_secret.json file
43
  client_config = {
44
  "installed": {
@@ -55,6 +74,7 @@ def get_drive_service():
55
  # Save the credentials for the next run
56
  with open(TOKEN_PICKLE_FILE, 'wb') as token:
57
  pickle.dump(creds, token)
 
58
 
59
  return build('drive', 'v3', credentials=creds)
60
 
 
1
  import os
2
  import pickle
3
+ import base64
4
  from google.auth.transport.requests import Request
5
  from google_auth_oauthlib.flow import InstalledAppFlow
6
  from googleapiclient.discovery import build
 
27
  def get_drive_service():
28
  """Authenticates with Google and returns a Drive service object."""
29
  creds = None
30
+
31
+ # --- NEW CODE FOR DEPLOYMENT ENVIRONMENTS ---
32
+ # If token file doesn't exist, try to create it from environment variable
33
+ if not os.path.exists(TOKEN_PICKLE_FILE):
34
+ encoded_token = os.environ.get('GOOGLE_TOKEN_BASE64')
35
+ if encoded_token:
36
+ logger.info("Found token in environment variable. Recreating token.pickle file.")
37
+ try:
38
+ decoded_token = base64.b64decode(encoded_token)
39
+ with open(TOKEN_PICKLE_FILE, "wb") as token_file:
40
+ token_file.write(decoded_token)
41
+ logger.info("Successfully recreated token.pickle from environment variable")
42
+ except Exception as e:
43
+ logger.error(f"Failed to decode token from environment variable: {e}")
44
+ # --- END OF NEW CODE ---
45
+
46
  # The file token.pickle stores the user's access and refresh tokens.
47
  if os.path.exists(TOKEN_PICKLE_FILE):
48
  with open(TOKEN_PICKLE_FILE, 'rb') as token:
 
51
  # If there are no (valid) credentials available, let the user log in.
52
  if not creds or not creds.valid:
53
  if creds and creds.expired and creds.refresh_token:
54
+ logger.info("Refreshing expired credentials")
55
  creds.refresh(Request())
56
  else:
57
  if not CLIENT_ID or not CLIENT_SECRET:
58
  raise ValueError("GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET environment variables are required")
59
 
60
+ logger.info("Starting OAuth flow for new credentials")
61
  # Use client_config dictionary instead of a client_secret.json file
62
  client_config = {
63
  "installed": {
 
74
  # Save the credentials for the next run
75
  with open(TOKEN_PICKLE_FILE, 'wb') as token:
76
  pickle.dump(creds, token)
77
+ logger.info("Saved new credentials to token.pickle")
78
 
79
  return build('drive', 'v3', credentials=creds)
80