Skip to content
Taimoor Arshad
Back to portfolio

AI Text Summarizer

2025Web · AI

Angular 19 frontend, ASP.NET Core 8 API, and a Flask service calling Google's Gemini Pro. Text in, summary out.

بسم الله الرحمن الرحيم

I built the AI Text Summarizer as part of a small batch of Angular + ASP.NET Core projects I put together to sharpen my full-stack chops for a dev role I was interviewing for. The idea itself is simple. Paste text in, get a summary back. The interesting part for me was the integration: I wanted to end up with three services running on three different providers, all talking to each other over HTTP, because that mirrors what a real cloud stack looks like in practice.

The stack

The frontend is Angular 19 with standalone components and plain CSS, deployed on Firebase Hosting. The backend API is ASP.NET Core 8 with C#, running on Azure App Service. The AI side is a Flask service on Render that wraps the Google Generative AI Python client for Gemini Pro, so the ASP.NET API doesn't have to talk to Google directly.

Why split it three ways

The obvious question is why not just call Gemini from the C# backend. There's an official Google client for .NET, and it would have been fewer moving parts. I went with a separate Python service for a few reasons.

The Python client for Gemini was better maintained at the time and easier to iterate on when Google AI Studio's API was still moving fast. Splitting the AI logic out meant I could swap models or providers behind Flask without touching the ASP.NET code. And I wanted the practice of standing up a Python service on a third provider (Render) and getting CORS, deploy pipelines, and env config to line up across all three.

The Flask service exposes a single endpoint that takes the text and returns the summary. The ASP.NET API sits in front of it, handles the frontend requests, and gives me a place to layer in rate limiting or caching later if I want.

What broke

The three-provider setup was the whole learning point, but it was also the whole difficulty.

  • Firebase to Azure CORS — first pass. The ASP.NET CORS middleware needs to explicitly whitelist the Firebase origin.

  • Azure to Render CORS — second pass, same shape as the first but for the Flask side. Flask's flask-cors package handles it in a few lines.

  • Render's cold starts — the free tier spins down when idle, so the first request after a quiet period would time out because the Flask service was still warming up. I ended up adding a "warming the model" state on the frontend so the user doesn't just see a spinner for 30 seconds without explanation.

Next steps

I'd like to swap the Flask layer for a serverless function so the cold-start problem goes away for real, and add a small cache in front of Gemini so identical inputs don't burn tokens twice. Long term, moving the whole thing to Vercel or a single provider would be cheaper to operate, but the three-provider setup did what I wanted it to do for the learning goal.

Try it at text-summarizer--textsummarizer-a2595.us-central1.hosted.app.