Close Menu
Versa AI hub
  • AI Ethics
  • AI Legislation
  • Business
  • Cybersecurity
  • Media and Entertainment
  • Content Creation
  • Art Generation
  • Research
  • Tools
  • Resources

Subscribe to Updates

Subscribe to our newsletter and stay updated with the latest news and exclusive offers.

What's Hot

Physical AI raises questions about governance of autonomous systems

May 5, 2026

The future of physical AI revealed in the LG and NVIDIA meeting

May 4, 2026

How to build scalable web apps using OpenAI privacy filters

May 3, 2026
Facebook X (Twitter) Instagram
Versa AI hubVersa AI hub
Tuesday, May 5
Facebook X (Twitter) Instagram
Login
  • AI Ethics
  • AI Legislation
  • Business
  • Cybersecurity
  • Media and Entertainment
  • Content Creation
  • Art Generation
  • Research
  • Tools
  • Resources
Versa AI hub
Home»Tools»How to build scalable web apps using OpenAI privacy filters
Tools

How to build scalable web apps using OpenAI privacy filters

versatileaiBy versatileaiMay 3, 2026No Comments7 Mins Read
Share Facebook Twitter Pinterest LinkedIn Tumblr Reddit Telegram Email
#image_title
Share
Facebook Twitter LinkedIn Pinterest Email

OpenAI released Privacy Filter on the Hub this week. This is an open-source Personally Identifiable Information (PII) detector that labels text across 8 categories in a single transfer over 128k contexts. model card. We spent several hours building with it and ended up with three apps that each reveal a different part of what they can do. Document Privacy Explorer: Drop a PDF or DOCX and read back the document with all PII spans highlighted in place. Image Anonymizer: Upload an image and it will come back edited with a black bar above your name, email address, and account number. Images can also be edited on canvas, so you can add your own annotations before downloading. SmartRedact Paste: Paste sensitive text, share the public URL that provides the redacted version, and keep the private public link for yourself.

All three are built on gradio.Server and allow you to combine your custom HTML/JS frontend with Gradio’s queuing, ZeroGPU allocation, and gradio_client SDKs. In all these apps, gradio.Server plays the same backend role, and that consistency is what makes it really powerful.

model

Privacy Filter is a 1.5B parameter model with 50 million active parameters and is licensed under Apache 2.0. PII categories are private_person, private_address, private_email, private_phone, private_url, private_date, account_number, and secret. The context is 128,000 tokens. Achieve cutting-edge performance with the PII-Masking-300k benchmark. Full numbers and methodology can be found on the official release blog.

1. Document Privacy Explorer

Try with ysharma/OPF-Document-PII-Explorer.

User issue. I want to read PII-rich documents (contracts, resumes, exported chat logs) with all detected spans highlighted by category, filters in the sidebar, and a summary dashboard at the top. The reading experience should feel like a regular document, not a format.

What a privacy filter does here. The entire file is processed in a single 128k context forward pass, so there’s no chunking or stitching, and span offsets match the rendered text directly. BIOES decoding keeps span boundaries clean through long ambiguous runs.

What gr.Server does here. If I connect this inside a block to gr.HighlightedText and the sidebar, it works. The reading experience we were looking for (dialogue body, category filters that toggle CSS classes on the client side instead of re-running the model, a summary dashboard that doesn’t force the page to re-render) was easier to hand-write than to write. gr.Server allows you to serve your reader view as a single HTML file and expose your model behind a single queued endpoint.

import gladio as grams
from fastapi.responses import HTML response
from gradio.data_classes import FileData Server = gr.Server()

@server.get(“https://huggingface.co/”response_class=HTML response)
asynchronous surely Home page():
return FRONTEND_HTML

@server.api(name =“Analyzing documents”)
surely Document analysis(File: File data) -> dictionary: text = extracted text(file(“path”))source_text, span = run_privacy_filter(text)
return {
“Sentence”: source text,
“span”: span,
“statistics”: compute_stats(source_text, span), }

Note the decorator @server.api(name=”analyze_document”). Not plain @server.post. This is the part that connects the handler to Gradio’s queue, so concurrent uploads are serialized, @spaces.GPU is correctly configured on ZeroGPU, and the same endpoint can be reached from both the browser and gradio_client without duplicating code. The browser calls this using the Gradio JS client.

script type=“Module”>
import { clienthandle file } from “https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js”;
constant Client = wait client.connect(window.position.origin);

asynchronous function upload file(file) {
constant Result = wait client.predict(“/analyze_document”,{ file: handle file(file) });
Rendering result(result.data(0));
}
script>

2. Image anonymizer

Try with ysharma/OPF-Image-Anonymizer.

User issue. I’d like to share an image or screenshot (Slack thread, receipt, Stripe dashboard) with a black bar over the PII. You want to turn bars on and off, drag them to reposition them, manually draw missing parts of your model, and then export the results.

What a privacy filter does here. Tesseract performs OCR and returns bounding boxes for each word. The backend reconstructs the full text from the character offset to the box map and runs the privacy filter once on the entire text. The found character spans are searched against the word map and combined into pixel rectangles line by line.

What gr.Server does here. gr.ImageEditor supports layered annotations and is a good starting point for image editing. The workflow we wanted (metadata per bar category, toggling all bars in a category at once, client-side PNG export at natural resolution without server roundtrips) was cleaner to build on top of a custom frontend. gr.Server returns a pixel rectangle from one queued endpoint and allows the canvas to own everything else.

@server.api(Name =“Anonymization_Screenshot”)
surely Anonymization_Screenshot(Image: File data) -> dictionary: img = image.open(image(“path”)). Convert (“RGB”) full_text, char_to_box = ocr_image(img) spans = run_privacy_filter(full_text) boxes = spans_to_pixel_boxes(spans, char_to_box)
return {
“Image data URL”: pil_to_base64(img),
“width”: image width,
“height”: image height,
“box”: box, }

The frontend calls this using client.predict(“/anonymize_screenshot”, { image: handle_file(file) }) with the same pattern as above. Toggling, dragging, drawing new bars, and PNG export all happen in the browser. Edits never go back and forth to the server.

3. Smart Reduct Paste

Try with ysharma/OPF-SmartRedact-Paste.

User issue. I need a pastebin to edit before sharing. Paste log lines, emails, and support tickets. Two URLs are returned. The published version follows the editing rules of the official blog example and provides an edited version using the , , and placeholders. Private ones are gated by the token they hold, and you’ll see the original with the span highlighted.

What a privacy filter does here. Replaces each detected span with a placeholder on the saved paste. This is the entire editing step. Multilingual text (Spanish, French, Chinese, Hindi, and others in the model card example) is routed through the same call without modification.

What gr.Server does here. This app requires two different GET routes for the same paste ID, one public and one TokenGate. The format of the URL is important because the public URL is what you want to maintain. gr.Server works here because it’s a FastAPI app underneath it. This is also why @server.api and plain @server.get can be placed next to each other in the same process. Note: This can also be built with gr.Blocks() by mounting a custom route with FastAPI.

@server.api(name =“Create_Paste”)
surely Create_Paste(Text: str,ttl: str = “Never”) -> dictionary:source_text, spans = run_privacy_filter(text) redacted = redact(source_text, spans) pid, reveal_token = Secrets.token_urlsafe(6), secrets.token_urlsafe(twenty two) PASTES(pid) = Paste(pid, reveal_token, source_text, edited, span, expires_at=_ttl(ttl))
return {
“View Pass”: f”/view/{pid}”,
“Public Pass”: f”/view/{pid}?token={reveal_token}”}

@server.get(“/view/{pid}”response_class=HTML response)
asynchronous surely Display_Paste(Pid: str,token: str | none = none): p = _store_get(pid)
if p teeth none:
return HTMLResponse(_not_found(), status_code=404) revealed = boule(token) and Secrets.compare_digest(token, p.reveal_token)
return HTMLResponse(_render_view(p, obviously))

A daemon thread deletes expired pastes every 30 seconds. The entire service, including storage, is approximately 200 lines of application code because everything resides in one process.

What gradio.Server provides

The splits for all three apps are the same. Everything related to the model goes through @server.api, everything else stays in the plain FastAPI route.

App Queued compute (@server.api) Plain FastAPI Root Document Privacy Exploreranalyze_document — Extract, Detect, Statistics GET / Provide custom reader view Image Anonymizer anonymize_screenshot — OCR, Detect, Span → Pixel Box GET / + GET /examples/* Provide canvas UI and preloaded examples SmartRedact Paste create_paste — Detect, Edit, Mint ID GET / Page creation, GET /view/{pid}?token=… public + token gated view, GET /api/paste/{pid} JSON lookup

@server.api provides Gradio’s queue (serialized requests, correct @spaces.GPU configuration on ZeroGPU, progress events) that the browser hits through @gradio/client. The same endpoint is also what the gradio_client user hit from Python: one function, two SDKs, no duplicate code. Plain @server.get/@server.post is reserved for static surfaces like HTML pages, file searches, and cheap dict reads. This is a rule of thumb from gradio.Server’s introductory post, and it’s why these three apps feel consistent even though their UIs are very different.

give it a try

Drop your resume, a screenshot of your Slack thread, and a log line with your token. The fun part is seeing what the privacy filter catches (and sometimes misses) in the text you’re actually interested in.

Recommended reading

author avatar
versatileai
See Full Bio
Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
Previous ArticlePer-token AI fees coming to GitHub Copilot
Next Article The future of physical AI revealed in the LG and NVIDIA meeting
versatileai

Related Posts

Tools

Physical AI raises questions about governance of autonomous systems

May 5, 2026
Tools

The future of physical AI revealed in the LG and NVIDIA meeting

May 4, 2026
Tools

Per-token AI fees coming to GitHub Copilot

May 3, 2026
Add A Comment

Comments are closed.

Top Posts

DeepInfra on Hug Face Inference Provider 🔥

May 2, 20266 Views

Soulgen revolutionizes the creation of NSFW content

May 11, 20256 Views

Per-token AI fees coming to GitHub Copilot

May 3, 20265 Views
Stay In Touch
  • YouTube
  • TikTok
  • Twitter
  • Instagram
  • Threads
Latest Reviews

Subscribe to Updates

Subscribe to our newsletter and stay updated with the latest news and exclusive offers.

Most Popular

DeepInfra on Hug Face Inference Provider 🔥

May 2, 20266 Views

Soulgen revolutionizes the creation of NSFW content

May 11, 20256 Views

Per-token AI fees coming to GitHub Copilot

May 3, 20265 Views
Don't Miss

Physical AI raises questions about governance of autonomous systems

May 5, 2026

The future of physical AI revealed in the LG and NVIDIA meeting

May 4, 2026

How to build scalable web apps using OpenAI privacy filters

May 3, 2026
Service Area
X (Twitter) Instagram YouTube TikTok Threads RSS
  • About Us
  • Contact Us
  • Privacy Policy
  • Terms and Conditions
  • Disclaimer
© 2026 Versa AI Hub. All Rights Reserved.

Type above and press Enter to search. Press Esc to cancel.

Sign In or Register

Welcome Back!

Login to your account below.

Lost password?