Spaces:
Sleeping
Sleeping
feat: add Hugging Face OAuth
Browse filesChrys-assisted
Summary:
- Enable Gradio Sign in with Hugging Face for the Space.
- Use scoped visitor OAuth tokens for dataset creation and updates.
- Install Gradio OAuth support through the locked uv environment.
Validation:
- uv sync --frozen
- Python compile and OAuth behavior smoke checks
- uv lock --check
- uv build
Conversation: https://app.warp.dev/conversation/f2ab5d06-489f-47ae-abd7-e9eced4d755f
Co-Authored-By: Oz <oz-agent@warp.dev>
- .gitignore +6 -0
- README.md +4 -0
- app.py +21 -19
- pyproject.toml +30 -0
- requirements.txt +0 -14
- uv.lock +0 -0
.gitignore
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.env
|
| 2 |
+
__pycache__/
|
| 3 |
+
*.pyc
|
| 4 |
+
.venv/
|
| 5 |
+
dist/
|
| 6 |
+
*.egg-info/
|
README.md
CHANGED
|
@@ -7,6 +7,10 @@ sdk: gradio
|
|
| 7 |
sdk_version: 5.20.1
|
| 8 |
app_file: app.py
|
| 9 |
pinned: false
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
---
|
| 11 |
|
| 12 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
| 7 |
sdk_version: 5.20.1
|
| 8 |
app_file: app.py
|
| 9 |
pinned: false
|
| 10 |
+
hf_oauth: true
|
| 11 |
+
hf_oauth_scopes:
|
| 12 |
+
- contribute-repos
|
| 13 |
+
- write-repos
|
| 14 |
---
|
| 15 |
|
| 16 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
app.py
CHANGED
|
@@ -18,7 +18,7 @@ from datasets.features import Image as HFImage
|
|
| 18 |
from huggingface_hub import HfApi, get_token
|
| 19 |
import huggingface_hub
|
| 20 |
import os
|
| 21 |
-
from mistralai
|
| 22 |
import fitz # pymupdf
|
| 23 |
from PIL import Image
|
| 24 |
import io
|
|
@@ -933,7 +933,7 @@ def get_hf_token(explicit_token: str | None = None) -> str | None:
|
|
| 933 |
def process_files(
|
| 934 |
file_paths: list[str],
|
| 935 |
chunk_size: int,
|
| 936 |
-
hf_token: str,
|
| 937 |
repo_name: str,
|
| 938 |
append_mode: bool = False,
|
| 939 |
min_chunk_chars: int = 20,
|
|
@@ -975,7 +975,7 @@ def process_files(
|
|
| 975 |
return (
|
| 976 |
"Error: No valid Hugging Face token found.\n"
|
| 977 |
"Please either:\n"
|
| 978 |
-
"1.
|
| 979 |
"2. Set HF_TOKEN environment variable\n"
|
| 980 |
"3. Run `huggingface-cli login` in your terminal"
|
| 981 |
)
|
|
@@ -1356,9 +1356,17 @@ else:
|
|
| 1356 |
|
| 1357 |
|
| 1358 |
def _gradio_process(
|
| 1359 |
-
file_objs
|
| 1360 |
-
|
| 1361 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1362 |
if not file_objs:
|
| 1363 |
return "Error: No files uploaded."
|
| 1364 |
if not isinstance(file_objs, list):
|
|
@@ -1367,7 +1375,7 @@ def _gradio_process(
|
|
| 1367 |
return process_files(
|
| 1368 |
file_paths,
|
| 1369 |
chunk_size,
|
| 1370 |
-
|
| 1371 |
repo_name,
|
| 1372 |
append_mode=append_mode,
|
| 1373 |
min_chunk_chars=min_chars,
|
|
@@ -1427,15 +1435,11 @@ with gr.Blocks(**GRADIO_BLOCKS_KWARGS) as demo:
|
|
| 1427 |
|
| 1428 |
with gr.Group(elem_classes=["mistral-section"]):
|
| 1429 |
gr.Markdown("### Hugging Face output")
|
|
|
|
| 1430 |
repo_name = gr.Textbox(
|
| 1431 |
label="Dataset repository",
|
| 1432 |
placeholder="your-username/your-dataset-name",
|
| 1433 |
)
|
| 1434 |
-
hf_token = gr.Textbox(
|
| 1435 |
-
label="Hugging Face token",
|
| 1436 |
-
type="password",
|
| 1437 |
-
placeholder="hf_... or set HF_TOKEN",
|
| 1438 |
-
)
|
| 1439 |
append_mode = gr.Checkbox(
|
| 1440 |
label="Append to existing dataset",
|
| 1441 |
value=False,
|
|
@@ -1465,7 +1469,7 @@ with gr.Blocks(**GRADIO_BLOCKS_KWARGS) as demo:
|
|
| 1465 |
)
|
| 1466 |
|
| 1467 |
gr.Markdown(
|
| 1468 |
-
"*Requires `MISTRAL_API_KEY`
|
| 1469 |
elem_classes=["mistral-note"],
|
| 1470 |
)
|
| 1471 |
|
|
@@ -1480,7 +1484,6 @@ with gr.Blocks(**GRADIO_BLOCKS_KWARGS) as demo:
|
|
| 1480 |
inputs=[
|
| 1481 |
file_input,
|
| 1482 |
chunk_size,
|
| 1483 |
-
hf_token,
|
| 1484 |
repo_name,
|
| 1485 |
append_mode,
|
| 1486 |
min_chars,
|
|
@@ -1491,14 +1494,13 @@ with gr.Blocks(**GRADIO_BLOCKS_KWARGS) as demo:
|
|
| 1491 |
|
| 1492 |
gr.Examples(
|
| 1493 |
examples=[
|
| 1494 |
-
[None, 512, "
|
| 1495 |
-
[None, 1024, "
|
| 1496 |
-
[None, 0, "
|
| 1497 |
],
|
| 1498 |
inputs=[
|
| 1499 |
file_input,
|
| 1500 |
chunk_size,
|
| 1501 |
-
hf_token,
|
| 1502 |
repo_name,
|
| 1503 |
append_mode,
|
| 1504 |
min_chars,
|
|
@@ -1520,4 +1522,4 @@ def main():
|
|
| 1520 |
|
| 1521 |
|
| 1522 |
if __name__ == "__main__":
|
| 1523 |
-
main()
|
|
|
|
| 18 |
from huggingface_hub import HfApi, get_token
|
| 19 |
import huggingface_hub
|
| 20 |
import os
|
| 21 |
+
from mistralai import Mistral
|
| 22 |
import fitz # pymupdf
|
| 23 |
from PIL import Image
|
| 24 |
import io
|
|
|
|
| 933 |
def process_files(
|
| 934 |
file_paths: list[str],
|
| 935 |
chunk_size: int,
|
| 936 |
+
hf_token: str | None,
|
| 937 |
repo_name: str,
|
| 938 |
append_mode: bool = False,
|
| 939 |
min_chunk_chars: int = 20,
|
|
|
|
| 975 |
return (
|
| 976 |
"Error: No valid Hugging Face token found.\n"
|
| 977 |
"Please either:\n"
|
| 978 |
+
"1. Sign in with Hugging Face when using the Space\n"
|
| 979 |
"2. Set HF_TOKEN environment variable\n"
|
| 980 |
"3. Run `huggingface-cli login` in your terminal"
|
| 981 |
)
|
|
|
|
| 1356 |
|
| 1357 |
|
| 1358 |
def _gradio_process(
|
| 1359 |
+
file_objs: list[str] | str | None,
|
| 1360 |
+
chunk_size: int,
|
| 1361 |
+
repo_name: str,
|
| 1362 |
+
append_mode: bool,
|
| 1363 |
+
min_chars: int,
|
| 1364 |
+
min_words: int,
|
| 1365 |
+
oauth_token: gr.OAuthToken | None,
|
| 1366 |
+
) -> str:
|
| 1367 |
+
"""Bridge between Gradio inputs, the signed-in user, and core processing."""
|
| 1368 |
+
if oauth_token is None:
|
| 1369 |
+
return "Error: Sign in with Hugging Face before processing files."
|
| 1370 |
if not file_objs:
|
| 1371 |
return "Error: No files uploaded."
|
| 1372 |
if not isinstance(file_objs, list):
|
|
|
|
| 1375 |
return process_files(
|
| 1376 |
file_paths,
|
| 1377 |
chunk_size,
|
| 1378 |
+
oauth_token.token,
|
| 1379 |
repo_name,
|
| 1380 |
append_mode=append_mode,
|
| 1381 |
min_chunk_chars=min_chars,
|
|
|
|
| 1435 |
|
| 1436 |
with gr.Group(elem_classes=["mistral-section"]):
|
| 1437 |
gr.Markdown("### Hugging Face output")
|
| 1438 |
+
gr.LoginButton()
|
| 1439 |
repo_name = gr.Textbox(
|
| 1440 |
label="Dataset repository",
|
| 1441 |
placeholder="your-username/your-dataset-name",
|
| 1442 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1443 |
append_mode = gr.Checkbox(
|
| 1444 |
label="Append to existing dataset",
|
| 1445 |
value=False,
|
|
|
|
| 1469 |
)
|
| 1470 |
|
| 1471 |
gr.Markdown(
|
| 1472 |
+
"*Requires `MISTRAL_API_KEY`. Sign in with Hugging Face before pushing a dataset.*",
|
| 1473 |
elem_classes=["mistral-note"],
|
| 1474 |
)
|
| 1475 |
|
|
|
|
| 1484 |
inputs=[
|
| 1485 |
file_input,
|
| 1486 |
chunk_size,
|
|
|
|
| 1487 |
repo_name,
|
| 1488 |
append_mode,
|
| 1489 |
min_chars,
|
|
|
|
| 1494 |
|
| 1495 |
gr.Examples(
|
| 1496 |
examples=[
|
| 1497 |
+
[None, 512, "hf-username/my-first-ocr-dataset", False, 20, 3],
|
| 1498 |
+
[None, 1024, "hf-username/large-chunk-ocr-data", True, 50, 5],
|
| 1499 |
+
[None, 0, "hf-username/no-split-ocr-data", False, 0, 0],
|
| 1500 |
],
|
| 1501 |
inputs=[
|
| 1502 |
file_input,
|
| 1503 |
chunk_size,
|
|
|
|
| 1504 |
repo_name,
|
| 1505 |
append_mode,
|
| 1506 |
min_chars,
|
|
|
|
| 1522 |
|
| 1523 |
|
| 1524 |
if __name__ == "__main__":
|
| 1525 |
+
main()
|
pyproject.toml
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[project]
|
| 2 |
+
name = "pdf2dataset"
|
| 3 |
+
version = "0.1.0"
|
| 4 |
+
description = "Convert PDF and image files into structured Hugging Face datasets using Mistral OCR"
|
| 5 |
+
readme = "README.md"
|
| 6 |
+
requires-python = ">=3.10"
|
| 7 |
+
license = { text = "MIT" }
|
| 8 |
+
|
| 9 |
+
dependencies = [
|
| 10 |
+
"gradio[oauth]>=5.20.1",
|
| 11 |
+
"datasets>=3.0.0",
|
| 12 |
+
"huggingface_hub>=0.25.0",
|
| 13 |
+
"mistralai>=1.0.0",
|
| 14 |
+
"pillow>=10.0.0",
|
| 15 |
+
"chonkie>=1.0.0",
|
| 16 |
+
"jsonschema>=4.0.0",
|
| 17 |
+
"python-dotenv>=1.2.1",
|
| 18 |
+
"pymupdf>=1.24.0",
|
| 19 |
+
]
|
| 20 |
+
|
| 21 |
+
[project.scripts]
|
| 22 |
+
pdf2dataset = "app:main"
|
| 23 |
+
|
| 24 |
+
[tool.hatch.build.targets.wheel]
|
| 25 |
+
packages = ["."]
|
| 26 |
+
only-include = ["app.py"]
|
| 27 |
+
|
| 28 |
+
[build-system]
|
| 29 |
+
requires = ["hatchling"]
|
| 30 |
+
build-backend = "hatchling.build"
|
requirements.txt
DELETED
|
@@ -1,14 +0,0 @@
|
|
| 1 |
-
gradio>=5.20.1
|
| 2 |
-
datasets>=3.0.0
|
| 3 |
-
huggingface_hub>=0.25.0
|
| 4 |
-
mistralai>=1.0.0
|
| 5 |
-
pillow>=10.0.0
|
| 6 |
-
chonkie>=1.0.0
|
| 7 |
-
jsonschema>=4.0.0
|
| 8 |
-
python-dotenv>=1.2.1
|
| 9 |
-
pymupdf>=1.24.0
|
| 10 |
-
langchain
|
| 11 |
-
langchain-community
|
| 12 |
-
langchain-openai
|
| 13 |
-
fastapi
|
| 14 |
-
python-multipart
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uv.lock
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|