Spaces:
Running
Running
File size: 7,150 Bytes
9896c32 aa140ba 9896c32 26eb7c3 f7727d2 26eb7c3 9896c32 f7727d2 ffc3f41 c1e8597 26eb7c3 9896c32 d905c00 f7727d2 26eb7c3 b9a446a 9896c32 26eb7c3 f7727d2 26eb7c3 f7727d2 26eb7c3 f7727d2 26eb7c3 9896c32 26eb7c3 9896c32 26eb7c3 c1e8597 9896c32 26eb7c3 c17eb23 f7727d2 8bfb138 d905c00 ffc3f41 d905c00 8bfb138 d905c00 f7727d2 d905c00 ffc3f41 d905c00 26eb7c3 d905c00 26eb7c3 d905c00 ffc3f41 26eb7c3 d905c00 f7727d2 c1e8597 f7727d2 acaddd8 c1e8597 c17eb23 f7727d2 c1e8597 acaddd8 c1e8597 f7727d2 c1e8597 ffc3f41 f7727d2 26eb7c3 aa140ba f7727d2 26eb7c3 9896c32 aa140ba 9896c32 f7727d2 9896c32 aa140ba 26eb7c3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
"""
Shared KGX3 API Endpoint – Calling KGX3 on PreprintWatch.com. Uploads research papers to the shared endpoint (secured with X-API-Key),
retrieves a signed temporary link, and sends it to the PreprintWatch KGX3 API. Output: JSON formatted Kuhnian Classification Report
"""
import gradio as gr
import requests, json, pathlib, mimetypes, re
# === CONFIGURATION ===
WP_UPLOAD_URL = "https://preprintwatch.com/wp-json/kgx3/v1/upload" # your WP REST route
WP_UPLOAD_KEY = "lmsijtadti7tiDD6750xNdN" # shared secret
API_ENDPOINT = "https://preprintwatch.com/wp-json/pw-kgx3/v1/submit" # KGX3 proxy
API_KEY = "sk-X1zY9wS3-vU4tQ0-rOjH5gK2fE7mN6" # internal KGX3 key
# === HELPERS ===
def upload_private_pdf(pdf_path: str) -> str:
"""Upload to WordPress secure uploader and return signed fetch URL."""
with open(pdf_path, "rb") as f:
r = requests.post(
WP_UPLOAD_URL,
headers={"X-API-Key": WP_UPLOAD_KEY},
files={"file": f},
timeout=60
)
r.raise_for_status()
data = r.json()
if "fetch_url" not in data:
raise RuntimeError(f"Upload failed: {data}")
return data["fetch_url"]
# === MAIN WORKFLOW ===
def call_kgx3(title, email, pdf_file, agreement):
if not agreement:
return "⚠️ You must accept the disclaimer before running KGX3.", ""
if not pdf_file:
return "Please select a PDF file.", ""
if not email or not re.match(r"[^@]+@[^@]+\.[^@]+", email):
return "A valid email address is required to run KGX3.", ""
pdf_path = pdf_file.name
if not pdf_path.lower().endswith(".pdf"):
return "Only PDF files are supported.", ""
# --- Upload to WP and get temporary signed URL ---
try:
file_url = upload_private_pdf(pdf_path)
except Exception as e:
return f"Upload error: {e}", ""
# --- Forward to KGX3 ---
headers = {"X-API-Key": API_KEY, "Content-Type": "application/json"}
payload = {"title": title or pathlib.Path(pdf_path).stem, "pdf_url": file_url, "email": email}
try:
resp = requests.post(API_ENDPOINT, headers=headers, json=payload, timeout=180)
try:
body = json.dumps(resp.json(), indent=2, ensure_ascii=False)
except Exception:
body = resp.text
return body, file_url
except requests.RequestException as e:
return f"Request error: {e}", file_url
# === STYLE (high-contrast Matrix aesthetic) ===
FUTURE_CSS = """
/* === UNIVERSAL RESET === */
html, body, .gradio-container, section, div, .form, .gr-block, .gr-panel, .gr-box, .gr-column, .gr-row, .container, .file-preview, .upload-box, .wrap-inner {
background-color: #000 !important;
color: #00ff99 !important;
font-family: 'Courier New', monospace !important;
box-sizing: border-box;
}
/* === GENERAL TEXT === */
* { color: #00ff99 !important; }
h1, h2, h3, label, .label {
font-weight: 700 !important;
text-transform: uppercase;
border-bottom: 1px solid #00ff99;
margin-bottom: 6px;
padding-bottom: 4px;
letter-spacing: 0.5px;
}
/* === CONTAINERS === */
.gr-box, .gr-panel, .gr-block, .gr-column, .gr-row, .form {
border: 1px solid #00ff99 !important;
border-radius: 6px;
background-color: #000 !important;
padding: 8px !important;
}
/* === INPUTS & TEXTAREAS === */
input, textarea, select {
background-color: #000 !important;
color: #00ff99 !important;
border: 1px solid #00ff99 !important;
border-radius: 4px;
padding: 6px 8px !important;
}
input:focus, textarea:focus {
outline: none !important;
border: 1px solid #00ffcc !important;
background-color: #001a10 !important;
}
::placeholder { color: #00ff99 !important; opacity: 0.6; }
/* === FILE UPLOAD === */
.upload-box, .file-preview, .wrap-inner, .file-preview-container {
background-color: #000 !important;
border: 2px solid #00ff99 !important;
border-radius: 6px !important;
padding: 10px !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
transition: all 0.2s ease-in-out;
}
.upload-box:hover, .file-preview:hover {
background-color: #001a10 !important;
border-color: #00ffaa !important;
}
/* === BUTTONS === */
button {
background-color: #000 !important;
color: #00ff99 !important;
border: 2px solid #00ff99 !important;
border-radius: 4px;
text-transform: uppercase;
font-weight: 700;
letter-spacing: 0.5px;
padding: 8px 16px !important;
transition: all 0.15s ease-in-out;
}
button:hover {
background-color: #00ff99 !important;
color: #000 !important;
}
/* === OUTPUT / CODE AREA === */
pre, code, .cm-editor, .cm-content, .cm-line, .output-html, .output-markdown {
background-color: #000 !important;
color: #00ff99 !important;
border: 1px solid #00ff99 !important;
border-radius: 6px;
padding: 10px !important;
font-size: 0.9rem;
}
/* === CHECKBOX === */
input[type=checkbox] {
accent-color: #00ff99 !important;
transform: scale(1.2);
}
/* === SCROLLBARS === */
::-webkit-scrollbar { width: 8px; background: #000; }
::-webkit-scrollbar-thumb { background: #00ff99; border-radius: 4px; }
/* === FOOTER === */
footer, .footer, small {
color: #00ff99 !important;
opacity: 0.8;
text-align: center;
letter-spacing: 0.4px;
}
"""
# === BUILD INTERFACE ===
with gr.Blocks(css=FUTURE_CSS, title="KGX3 Research Analyzer") as demo:
gr.Markdown("""
# **KGX3 Engine**
Upload a scientific preprint PDF. The app sends it to the shared KGX3 API endpoint demonstrating the API function.
""")
# --- Disclaimer ---
gr.Markdown("""
### ⚠️ Disclaimer
By using this interface, you confirm that:
- You are responsible and accountable for the files you upload.
- All uploaded files are automatically deleted within **24 hours**.
- System logs of KGX3 activity are retained securely for **up to 60 days** for auditing.
- You must ensure that any material you upload is lawful, non-confidential, and free of third-party rights restrictions.
""")
agreement = gr.Checkbox(
label="I have read and accept full responsibility and accountability for the files I upload.",
value=False
)
# --- Layout ---
with gr.Row():
with gr.Column(scale=1):
title_box = gr.Textbox(label="Enter the paper title", placeholder="Enter or paste the paper title")
email_box = gr.Textbox(label="Email (required)", placeholder="you@example.com")
file_box = gr.File(label="Upload PDF", file_types=[".pdf"], type="filepath")
run_btn = gr.Button("Run KGX3", variant="primary")
with gr.Column(scale=1):
output_json = gr.Code(label="KGX3 Response", language="json")
output_url = gr.Textbox(label="Temporary PDF Link", interactive=False)
run_btn.click(call_kgx3,
inputs=[title_box, email_box, file_box, agreement],
outputs=[output_json, output_url])
gr.Markdown("<small>Built on Gradio • Thomas Kuhn Foundation © All rights reserved.</small>")
demo.launch()
|