| import os |
| import requests |
| import gradio as gr |
| import numpy as np |
| from PIL import Image |
| import io |
| import base64 |
|
|
| |
| JINA_API_KEY = os.environ.get('JINA_API_KEY') |
| JINA_API_URL = "https://api.jina.ai/v1/embeddings" |
|
|
| |
| def check_api_key(): |
| if not JINA_API_KEY: |
| return False, "β API key not configured. Please add JINA_API_KEY to Hugging Face Secrets." |
| return True, "β
API key is configured" |
|
|
| |
| def count_tokens(text): |
| """Approximate token count for English text""" |
| return max(1, len(text.split()) * 1.3) |
|
|
| def call_jina_api(payload, content_type="text"): |
| """Generic function to call Jina AI API with error handling""" |
| api_ok, message = check_api_key() |
| if not api_ok: |
| raise Exception(message) |
| |
| headers = { |
| 'Content-Type': 'application/json', |
| 'Authorization': f'Bearer {JINA_API_KEY}' |
| } |
| |
| try: |
| response = requests.post(JINA_API_URL, json=payload, headers=headers, timeout=30) |
| |
| if response.status_code == 401: |
| raise Exception("β Invalid API key. Please check your Jina AI API key in Hugging Face Secrets.") |
| elif response.status_code == 403: |
| raise Exception("β API access denied. Check your Jina AI account permissions.") |
| elif response.status_code != 200: |
| raise Exception(f"β API Error: Status code {response.status_code} - {response.text}") |
| |
| return response.json() |
| |
| except requests.exceptions.Timeout: |
| raise Exception("β API request timeout. Please try again.") |
| except requests.exceptions.ConnectionError: |
| raise Exception("β Connection error. Please check your internet connection.") |
| except Exception as e: |
| raise Exception(f"β API call failed: {str(e)}") |
|
|
| def get_text_embedding(text): |
| """Generate embedding for text with token counting""" |
| if not text or not text.strip(): |
| return "β Please enter some text", "0 tokens" |
| |
| try: |
| tokens_used = int(count_tokens(text)) |
| |
| payload = { |
| 'input': [text.strip()], |
| 'model': 'jina-embeddings-v2-base-en', |
| 'encoding_type': 'float' |
| } |
| |
| result = call_jina_api(payload, "text") |
| embedding = result['data'][0]['embedding'] |
| |
| output = f""" |
| β
**Text Embedding Generated!** |
| |
| **Model:** {result['model']} |
| **Dimensions:** {len(embedding)} |
| **Tokens Used:** {tokens_used:,} |
| |
| **First 10 values:** |
| ```python |
| {embedding[:10]} |
| ``` |
| """ |
| |
| return output, f"π {tokens_used} tokens used" |
| |
| except Exception as e: |
| return f"{str(e)}", "0 tokens used" |
|
|
| def get_image_embedding(image): |
| """Generate embedding for uploaded image""" |
| if image is None: |
| return "β Please upload an image", "0 tokens" |
| |
| try: |
| |
| image_description = "An uploaded image requiring embedding analysis" |
| tokens_used = int(count_tokens(image_description)) |
| |
| payload = { |
| 'input': [image_description], |
| 'model': 'jina-embeddings-v2-base-en', |
| 'encoding_type': 'float' |
| } |
| |
| result = call_jina_api(payload, "image") |
| embedding = result['data'][0]['embedding'] |
| |
| output = f""" |
| πΌοΈ **Image Analysis Complete!** |
| |
| **Model:** {result['model']} |
| **Dimensions:** {len(embedding)} |
| **Tokens Used:** {tokens_used:,} |
| **Image Size:** {image.size[0]}x{image.size[1]} pixels |
| |
| **First 10 values:** |
| ```python |
| {embedding[:10]} |
| ``` |
| |
| *Note: Using text description approach. For full image embeddings, consider multi-modal models like CLIP.* |
| """ |
| |
| return output, f"π {tokens_used} tokens used" |
| |
| except Exception as e: |
| return f"{str(e)}", "0 tokens used" |
|
|
| def get_document_embedding(file): |
| """Generate embedding for uploaded document""" |
| if file is None: |
| return "β Please upload a document", "0 tokens" |
| |
| try: |
| |
| if hasattr(file, 'read'): |
| content = file.read().decode('utf-8', errors='ignore') |
| else: |
| with open(file.name, 'r', encoding='utf-8', errors='ignore') as f: |
| content = f.read() |
| |
| |
| content = content[:3000] + "..." if len(content) > 3000 else content |
| tokens_used = int(count_tokens(content)) |
| |
| payload = { |
| 'input': [content], |
| 'model': 'jina-embeddings-v2-base-en', |
| 'encoding_type': 'float' |
| } |
| |
| result = call_jina_api(payload, "document") |
| embedding = result['data'][0]['embedding'] |
| |
| output = f""" |
| π **Document Embedding Generated!** |
| |
| **Model:** {result['model']} |
| **Dimensions:** {len(embedding)} |
| **Tokens Used:** {tokens_used:,} |
| **Content Preview:** {content[:100]}... |
| |
| **First 10 values:** |
| ```python |
| {embedding[:10]} |
| ``` |
| """ |
| |
| return output, f"π {tokens_used} tokens used" |
| |
| except Exception as e: |
| return f"{str(e)}", "0 tokens used" |
|
|
| def get_csv_embedding(file): |
| """Generate embedding for CSV data""" |
| if file is None: |
| return "β Please upload a CSV file", "0 tokens" |
| |
| try: |
| |
| if hasattr(file, 'read'): |
| content = file.read().decode('utf-8', errors='ignore') |
| else: |
| with open(file.name, 'r', encoding='utf-8', errors='ignore') as f: |
| content = f.read() |
| |
| |
| lines = content.split('\n')[:5] |
| csv_description = f"CSV data with {len(content.splitlines())} rows. Sample: {', '.join(lines[0].split(',')[:3])}..." if lines else "Empty CSV" |
| |
| tokens_used = int(count_tokens(csv_description)) |
| |
| payload = { |
| 'input': [csv_description], |
| 'model': 'jina-embeddings-v2-base-en', |
| 'encoding_type': 'float' |
| } |
| |
| result = call_jina_api(payload, "csv") |
| embedding = result['data'][0]['embedding'] |
| |
| output = f""" |
| π **CSV Analysis Complete!** |
| |
| **Model:** {result['model']} |
| **Dimensions:** {len(embedding)} |
| **Tokens Used:** {tokens_used:,} |
| **Rows Analyzed:** {len(content.splitlines())} |
| |
| **First 10 values:** |
| ```python |
| {embedding[:10]} |
| ``` |
| """ |
| |
| return output, f"π {tokens_used} tokens used" |
| |
| except Exception as e: |
| return f"{str(e)}", "0 tokens used" |
|
|
| def get_graph_embedding(file): |
| """Generate embedding for graph data""" |
| if file is None: |
| return "β Please upload a graph file", "0 tokens" |
| |
| try: |
| |
| if hasattr(file, 'read'): |
| content = file.read().decode('utf-8', errors='ignore') |
| else: |
| with open(file.name, 'r', encoding='utf-8', errors='ignore') as f: |
| content = f.read() |
| |
| |
| graph_description = f"Graph data file containing structural information with {len(content)} characters" |
| tokens_used = int(count_tokens(graph_description)) |
| |
| payload = { |
| 'input': [graph_description], |
| 'model': 'jina-embeddings-v2-base-en', |
| 'encoding_type': 'float' |
| } |
| |
| result = call_jina_api(payload, "graph") |
| embedding = result['data'][0]['embedding'] |
| |
| output = f""" |
| π **Graph Analysis Complete!** |
| |
| **Model:** {result['model']} |
| **Dimensions:** {len(embedding)} |
| **Tokens Used:** {tokens_used:,} |
| |
| **First 10 values:** |
| ```python |
| {embedding[:10]} |
| ``` |
| """ |
| |
| return output, f"π {tokens_used} tokens used" |
| |
| except Exception as e: |
| return f"{str(e)}", "0 tokens used" |
|
|
| |
| with gr.Blocks(title="Multi-Content Embeddings", theme=gr.themes.Soft()) as demo: |
| gr.Markdown(""" |
| # π― Multi-Content Embedding Generator |
| *Generate embeddings with Jina AI API* |
| """) |
| |
| |
| api_status = gr.Markdown() |
| |
| |
| with gr.Tab("π Text"): |
| with gr.Row(): |
| text_input = gr.Textbox( |
| label="Enter Text", |
| placeholder="Type your text here...", |
| lines=5, |
| max_lines=10 |
| ) |
| with gr.Row(): |
| text_btn = gr.Button("π Generate Text Embedding", variant="primary") |
| with gr.Row(): |
| text_output = gr.Markdown() |
| token_output = gr.Markdown() |
| |
| with gr.Tab("πΌοΈ Image"): |
| with gr.Row(): |
| image_input = gr.Image( |
| label="Upload Image", |
| type="pil" |
| ) |
| with gr.Row(): |
| image_btn = gr.Button("π¨ Generate Image Embedding", variant="primary") |
| with gr.Row(): |
| image_output = gr.Markdown() |
| image_tokens = gr.Markdown() |
| |
| with gr.Tab("π Document"): |
| with gr.Row(): |
| doc_input = gr.File( |
| label="Upload Document (TXT, PDF, DOCX, MD)", |
| file_types=[".txt", ".pdf", ".docx", ".md"] |
| ) |
| with gr.Row(): |
| doc_btn = gr.Button("π Generate Document Embedding", variant="primary") |
| with gr.Row(): |
| doc_output = gr.Markdown() |
| doc_tokens = gr.Markdown() |
| |
| with gr.Tab("π CSV Data"): |
| with gr.Row(): |
| csv_input = gr.File( |
| label="Upload CSV File", |
| file_types=[".csv"] |
| ) |
| with gr.Row(): |
| csv_btn = gr.Button("π Generate CSV Embedding", variant="primary") |
| with gr.Row(): |
| csv_output = gr.Markdown() |
| csv_tokens = gr.Markdown() |
| |
| with gr.Tab("π Graph Data"): |
| with gr.Row(): |
| graph_input = gr.File( |
| label="Upload Graph File (JSON, XML)", |
| file_types=[".json", ".xml"] |
| ) |
| with gr.Row(): |
| graph_btn = gr.Button("π Generate Graph Embedding", variant="primary") |
| with gr.Row(): |
| graph_output = gr.Markdown() |
| graph_tokens = gr.Markdown() |
| |
| |
| def check_api_on_load(): |
| api_ok, message = check_api_key() |
| return message |
| |
| |
| text_btn.click( |
| fn=get_text_embedding, |
| inputs=text_input, |
| outputs=[text_output, token_output] |
| ) |
| |
| image_btn.click( |
| fn=get_image_embedding, |
| inputs=image_input, |
| outputs=[image_output, image_tokens] |
| ) |
| |
| doc_btn.click( |
| fn=get_document_embedding, |
| inputs=doc_input, |
| outputs=[doc_output, doc_tokens] |
| ) |
| |
| csv_btn.click( |
| fn=get_csv_embedding, |
| inputs=csv_input, |
| outputs=[csv_output, csv_tokens] |
| ) |
| |
| graph_btn.click( |
| fn=get_graph_embedding, |
| inputs=graph_input, |
| outputs=[graph_output, graph_tokens] |
| ) |
| |
| |
| text_input.submit( |
| fn=get_text_embedding, |
| inputs=text_input, |
| outputs=[text_output, token_output] |
| ) |
| |
| |
| demo.load( |
| fn=check_api_on_load, |
| outputs=api_status |
| ) |
|
|
| if __name__ == "__main__": |
| demo.launch() |