fcakyon commited on
Commit
fca1361
·
verified ·
1 Parent(s): a7e3757

refactor: simplify app.py

Browse files
Files changed (1) hide show
  1. app.py +51 -116
app.py CHANGED
@@ -1,139 +1,74 @@
1
  import os
2
  import gradio as gr
3
- from urllib.request import urlretrieve
4
- from utils import (
5
- EXAMPLE_ITEMS,
6
- analyze_image_with_status,
7
- run_example_by_index,
8
- )
9
 
10
- VIDDEXA_TOKEN = os.getenv("HF_TOKEN")
 
11
 
12
- CUSTOM_CSS = """
13
- .verdict-safe { background-color: #D5F5E3; border: 2px solid #2ECC71; color: #1D8348; }
14
- .verdict-sensitive { background-color: #FCF3CF; border: 2px solid #F1C40F; color: #B7950B; }
15
- .verdict-nsfw { background-color: #FADBD8; border: 2px solid #E74C3C; color: #B03A2E; }
16
- .verdict-card { padding: 20px; border-radius: 10px; text-align: center; font-size: 24px; font-weight: bold; }
17
- .viddexa-logo { background-color: #FFFFFF; padding: 8px; border-radius: 8px; }
18
- footer {visibility: hidden}
19
- """
20
-
21
- with gr.Blocks(
22
- theme=gr.themes.Default(primary_hue=gr.themes.colors.teal),
23
- title="Visual Content Moderation",
24
- css=CUSTOM_CSS,
25
- analytics_enabled=False,
26
- ) as demo:
27
- gr.HTML("""
28
- <div class="viddexa-header" style="text-align: center; max-width: 800px; margin: 0 auto;">
29
- <img class="viddexa-logo" src="https://aky-tech.com/images/viddexa-logo.svg" alt="Viddexa logo" style="max-width: 320px; width: 80%; height: auto; display: block; margin: 10px auto 6px;" />
30
- <p style="font-size: 1.2em; color: #888;">
31
- Official demo for <a href="https://github.com/viddexa/moderators" target="_blank"><code>moderators</code></a> package.
32
- <br>
33
- Upload an image or provide a URL to get an instant content analysis.
34
- </p>
35
- <p>
36
- 🔗 <b>Project Links:</b>
37
- <a href="https://huggingface.co/viddexa/nsfw-mini" target="_blank">[Model: nsfw-mini]</a> |
38
- <a href="https://huggingface.co/viddexa/nsfw-nano" target="_blank">[Model: nsfw-nano]</a> |
39
- <a href="https://arxiv.org/abs/2312.16338" target="_blank">[Arxiv]</a> |
40
- <a href="https://github.com/viddexa/moderators" target="_blank">[GitHub]</a> |
41
- <a href="https://pypi.org/project/moderators/" target="_blank">[PyPI]</a>
42
- </p>
43
- <p>
44
- <details style="margin-top: 10px;">
45
- <summary style="cursor: pointer; font-weight: bold;">📄 BibTeX entry for citation</summary>
46
- <pre style="background-color: rgba(128, 128, 128, 0.1); border: 1px solid rgba(128, 128, 128, 0.3); padding: 15px; border-radius: 5px; text-align: left; overflow-x: auto; margin: 10px 0;"><code style="font-family: monospace;">@article{akyon2023nudity,
47
  title={State-of-the-art in nudity classification: A comparative analysis},
48
  author={Akyon, Fatih Cagatay and Temizel, Alptekin},
49
  booktitle={2023 IEEE International Conference on Acoustics, Speech, and Signal Processing Workshops (ICASSPW)},
50
  pages={1--5},
51
  year={2023},
52
  organization={IEEE}
53
- }</code></pre>
54
- </details>
55
- </p>
56
- </div>
57
- """)
58
-
59
- with gr.Row(variant="panel"):
60
- with gr.Column(scale=1, min_width=350):
61
- gr.Markdown("## ⚙️ Step 1: Configure Settings")
62
  model_choice = gr.Dropdown(
63
  choices=["viddexa/nsfw-detection-mini", "viddexa/nsfw-detection-nano"],
64
  value="viddexa/nsfw-detection-mini",
65
- label="Moderation Model",
66
- info="Choose the faster 'nano' or the better 'mini' model.",
67
  )
68
-
69
- gr.Markdown("## 🖼️ Step 2: Provide an Image")
70
  with gr.Tabs():
71
- with gr.TabItem("Upload Image"):
72
- image_input = gr.Image(type="filepath", label="Drag & drop a file or click to upload")
73
- with gr.TabItem("From URL"):
74
- image_url_input = gr.Textbox(
75
- label="Image URL",
76
- placeholder="https://example.com/image.jpg",
77
- )
78
-
79
- run_btn = gr.Button("Start Analysis", variant="primary", scale=2)
80
-
81
- with gr.Column(scale=2, min_width=500):
82
- gr.Markdown("## 📊 Step 3: Review Results")
83
- verdict_output = gr.HTML(label="Final Verdict")
84
- label_output = gr.Label(label="Classification Scores", num_top_classes=4, show_label=True)
85
- markdown_output = gr.Markdown(label="All Scores")
86
-
87
- with gr.Accordion("Show Raw JSON Output", open=False):
88
- json_output = gr.JSON(label="Model Output (JSON)")
89
-
90
- gr.Markdown("## 🎯 Try an Example (click an image)")
91
- gallery_items = [[url, caption] for (url, _model, caption) in EXAMPLE_ITEMS]
92
- examples_gallery = gr.Gallery(
93
- label="Try an Example",
94
- value=gallery_items,
95
  columns=[2, 4],
96
  height=200,
97
  allow_preview=False,
98
  )
99
-
100
- status_md = gr.Markdown("Last analysed: —", elem_id="last-example-status")
101
-
102
- examples_gallery.select(
103
- fn=lambda evt: run_example_by_index(evt, VIDDEXA_TOKEN),
104
- outputs=[
105
- verdict_output,
106
- label_output,
107
- markdown_output,
108
- json_output,
109
- model_choice,
110
- image_url_input,
111
- status_md,
112
- ],
113
  )
114
-
115
- run_btn.click(
116
- fn=lambda img, url, model, progress: analyze_image_with_status(img, url, model, VIDDEXA_TOKEN, progress),
117
- inputs=[image_input, image_url_input, model_choice],
118
- outputs=[verdict_output, label_output, markdown_output, json_output, status_md],
119
  )
120
 
121
- gr.HTML("""
122
- <div style="text-align: center; margin-top: 20px; color: #888;">
123
- <p>Developed by Viddexa.</p>
124
- </div>
125
- """)
126
-
127
- if not os.path.exists("examples"):
128
- os.makedirs("examples")
129
- print("Created 'examples' directory.")
130
- try:
131
- urlretrieve(
132
- "https://images.pexels.com/photos/36717/amazing-animal-beautiful-beautifull.jpg",
133
- "examples/safe_nature.jpg"
134
- )
135
- print("Downloaded an example image to 'examples/safe_nature.jpg'")
136
- except Exception as e:
137
- print(f"Could not download example image: {e}")
138
-
139
  demo.launch()
 
1
  import os
2
  import gradio as gr
3
+ from dotenv import load_dotenv
4
+ from utils import EXAMPLE_ITEMS, analyze, run_example
 
 
 
 
5
 
6
+ load_dotenv()
7
+ TOKEN = os.getenv("HF_TOKEN")
8
 
9
+ with gr.Blocks(title="Visual Content Moderation") as demo:
10
+ gr.Markdown("# Viddexa - Visual Content Moderation")
11
+ gr.Markdown("Official demo for [moderators](https://github.com/viddexa/moderators) package.")
12
+ gr.Markdown("Upload an image or provide a URL to get an instant content analysis.")
13
+ gr.Markdown(
14
+ "🔗 **Project Links:** "
15
+ "[Model: nsfw-mini](https://huggingface.co/viddexa/nsfw-mini) | "
16
+ "[Model: nsfw-nano](https://huggingface.co/viddexa/nsfw-nano) | "
17
+ "[Arxiv](https://arxiv.org/abs/2312.16338) | "
18
+ "[GitHub](https://github.com/viddexa/moderators) | "
19
+ "[PyPI](https://pypi.org/project/moderators/)"
20
+ )
21
+
22
+ with gr.Accordion("📄 BibTeX entry for citation", open=False):
23
+ gr.Code(
24
+ value="""@article{akyon2023nudity,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  title={State-of-the-art in nudity classification: A comparative analysis},
26
  author={Akyon, Fatih Cagatay and Temizel, Alptekin},
27
  booktitle={2023 IEEE International Conference on Acoustics, Speech, and Signal Processing Workshops (ICASSPW)},
28
  pages={1--5},
29
  year={2023},
30
  organization={IEEE}
31
+ }""",
32
+ language="bibtex",
33
+ show_label=False,
34
+ )
35
+
36
+ with gr.Row():
37
+ with gr.Column(scale=1):
 
 
38
  model_choice = gr.Dropdown(
39
  choices=["viddexa/nsfw-detection-mini", "viddexa/nsfw-detection-nano"],
40
  value="viddexa/nsfw-detection-mini",
41
+ label="Model",
 
42
  )
43
+
 
44
  with gr.Tabs():
45
+ with gr.TabItem("Upload"):
46
+ image_input = gr.Image(type="filepath", label="Image")
47
+ with gr.TabItem("URL"):
48
+ url_input = gr.Textbox(label="Image URL", placeholder="https://...")
49
+
50
+ analyze_btn = gr.Button("Analyze", variant="primary")
51
+
52
+ with gr.Column(scale=1):
53
+ output = gr.Label(label="Classification Scores", num_top_classes=10)
54
+
55
+ gr.Markdown("### Examples")
56
+ gallery = gr.Gallery(
57
+ value=[[url, f"Example {i+1}"] for i, (url, _) in enumerate(EXAMPLE_ITEMS)],
 
 
 
 
 
 
 
 
 
 
 
58
  columns=[2, 4],
59
  height=200,
60
  allow_preview=False,
61
  )
62
+
63
+ analyze_btn.click(
64
+ fn=lambda img, url, model: analyze(img, url, model, TOKEN),
65
+ inputs=[image_input, url_input, model_choice],
66
+ outputs=output,
 
 
 
 
 
 
 
 
 
67
  )
68
+
69
+ gallery.select(
70
+ fn=lambda evt: run_example(evt, TOKEN),
71
+ outputs=[output, model_choice, url_input],
 
72
  )
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  demo.launch()