{"id":31767652,"url":"https://github.com/adithya2369/safa_public","last_synced_at":"2025-10-10T01:18:40.875Z","repository":{"id":317862464,"uuid":"1069121179","full_name":"Adithya2369/safa_public","owner":"Adithya2369","description":"AI-powered customer feedback analyzer that uses generative AI to transform customer reviews into actionable business insights. Upload review data, get instant summaries, satisfaction scores, detailed reports, and improvement suggestions—all in an easy-to-deploy Docker container. ","archived":false,"fork":false,"pushed_at":"2025-10-03T13:20:11.000Z","size":3114,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-03T15:25:16.077Z","etag":null,"topics":["data-analysis","data-visualization","docker-containerization","full-stack-development","generative-ai","langchain","langchain-groq","web-development"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Adithya2369.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-03T12:42:21.000Z","updated_at":"2025-10-03T13:20:15.000Z","dependencies_parsed_at":"2025-10-03T15:26:24.918Z","dependency_job_id":"c70e211b-e107-485f-a6cc-72e3856fb5d9","html_url":"https://github.com/Adithya2369/safa_public","commit_stats":null,"previous_names":["adithya2369/safa_public"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/Adithya2369/safa_public","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Adithya2369%2Fsafa_public","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Adithya2369%2Fsafa_public/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Adithya2369%2Fsafa_public/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Adithya2369%2Fsafa_public/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Adithya2369","download_url":"https://codeload.github.com/Adithya2369/safa_public/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Adithya2369%2Fsafa_public/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279002398,"owners_count":26083373,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data-analysis","data-visualization","docker-containerization","full-stack-development","generative-ai","langchain","langchain-groq","web-development"],"created_at":"2025-10-10T01:18:33.963Z","updated_at":"2025-10-10T01:18:40.870Z","avatar_url":"https://github.com/Adithya2369.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SAFA — Customer Feedback Analyser\n\n\u003e **SAFA (S**tands for **Customer Feedback Analyser)** — A compact Flask-based web app that transforms customer reviews into actionable business insights using Groq / LangChain prompts. Upload an Excel file containing reviews, get per-review summaries + sentiment tagging, a dashboard with aggregate stats, and longer analysis \u0026 suggested improvements.\n\n---\n\n## 1. Project overview\n\nSAFA is a small, easy-to-run customer feedback analyser built with Flask. It relies on prompt-driven LLM calls (Groq via `langchain-groq`) to:\n\n- Summarize each review into a compact statement + a satisfaction number.\n- Tag reviews into categories (e.g. product quality, delivery, price).\n- Produce an aggregate analysis report and suggested improvements.\n\nThe UI is minimal (Flask + simple templates). The app is packaged with a `Dockerfile` so you can run it in a container. The app stores any uploaded Excel file inside the `uploads/` folder as `stored_excel_file.xlsx` and reads the `Text` column to obtain reviews.\n\n---\n\n## 2. Features\n\n- Upload Excel (`.xlsx / .xls`) containing customer reviews and ratings.\n- Per-review summarization and sentiment detection.\n- Tagging of reviews into categories.\n- Dashboard showing average rating, predicted satisfaction score and a table of processed reviews.\n- Analysis report (long-form) and suggested improvements (actionable items).\n- Several friendly error pages (404, 500, 502, 503).\n\n---\n\n## 3. Quick start (Docker)\n\n\u003e Note: this repo contains a `Dockerfile` so you can build and run the container quickly.\n\nBuild and run locally:\n\n```bash\n# Build image in the repository root\ndocker build -t safa_public:latest .\n\n# Run container (example — set the Groq keys as environment variables)\ndocker run --rm -p 5000:5000 \\\n  -e summarize_key=\"\u003cYOUR_GROQ_KEY\u003e\" \\\n  -e tag_key=\"\u003cYOUR_GROQ_KEY\u003e\" \\\n  -e analysis_key=\"\u003cYOUR_GROQ_KEY\u003e\" \\\n  -e improvements_key=\"\u003cYOUR_GROQ_KEY\u003e\" \\\n  safa_public:latest\n```\n\nWhen the container is running, open `http://localhost:5000` in your browser.\n\n**Notes:** the Dockerfile uses `python:3.12-slim` as the base image and creates `/app/uploads` inside the container (so uploaded files persist inside the container file system until removed). See the Dockerfile for exact build steps.\n\n---\n\n## 4. Quick start (local — Python)\n\nPrerequisites:\n\n- Python 3.12 (recommended — the Dockerfile uses `python:3.12-slim`).\n- `pip` and a virtual environment (recommended).\n\nInstall \u0026 run:\n\n```bash\npython -m venv venv\nsource venv/bin/activate   # or venv\\Scripts\\activate on Windows\npip install --upgrade pip\npip install -r requirements.txt\n\n# Export required env variables (example)\nexport summarize_key=\"\u003cYOUR_GROQ_KEY\u003e\"\nexport tag_key=\"\u003cYOUR_GROQ_KEY\u003e\"\nexport analysis_key=\"\u003cYOUR_GROQ_KEY\u003e\"\nexport improvements_key=\"\u003cYOUR_GROQ_KEY\u003e\"\n\npython app.py\n```\n\nOpen `http://localhost:5000`\n\n---\n\n## 5. Environment variables \u0026 models\n\nThe application expects the following environment variables (used inside `app_functions.py`):\n\n- `summarize_key` — Groq API key used by the summarization prompt.\n- `tag_key` — Groq API key used for the tagging prompt.\n- `analysis_key` — Groq API key used for the analysis report.\n- `improvements_key` — Groq API key used for suggested improvements.\n\nOptional model environment variables (fallback defaults are set in the code):\n\n- `summarize_model` (default: `llama-3.3-70b-versatile`)\n- `tag_model` (default: `llama-3.3-70b-versatile`)\n- `analysis_model` (default: `qwen/qwen3-32b`)\n- `improvements_model` (default: `qwen/qwen3-32b`)\n\n**Important:** Do **not** commit API keys to source control. Use `.env` files excluded by `.gitignore`, Docker secrets, or environment variables in your deployment platform.\n\n---\n\n## 6. Input file format\n\nThe app expects an Excel workbook where reviews are stored in a column named exactly **`Text`** and ratings (numerical) are stored in a column named exactly **`Rating`**.\n\nMinimum example (Excel):\n\n| Text                                     | Rating |\n|------------------------------------------|--------|\n| \"Product arrived late but works fine\"   | 4      |\n| \"Battery died in 2 days, very unhappy\"  | 1      |\n\nWhen you upload a file via the UI it is saved as `uploads/stored_excel_file.xlsx` and then processed.\n\n---\n\n## 7. Project layout (file-by-file)\n\n```\n├── Dockerfile                # Builds a python:3.12-slim image and installs requirements\n├── app.py                    # Flask app (routes, upload, dashboard, error handlers)\n├── app_functions.py          # Core logic that calls Groq via langchain-groq (summarize, tag, analyze)\n├── requirements.txt          # Python dependencies\n├── templates/                # Flask templates (home, upload, dashboard, analysis, suggest, safa, errors)\n├── static/                   # static assets (CSS etc — minimal)\n└── uploads/                  # runtime uploads (stored_excel_file.xlsx)\n```\n\nShort descriptions:\n\n- `app.py` — Hosts the Flask routes: `/` (home), `/upload` (file upload), `/dashboard`, `/analysis`, `/suggest`, `/safa`. It calls helper functions in `app_functions.py` and renders templates. The uploaded file is saved as `uploads/stored_excel_file.xlsx` (see `process_excel()` and `/upload` route).\n\n- `app_functions.py` — Implements:\n  - `summarize(text_dict)` — creates a prompt and calls `ChatGroq` to produce CSV text (summaries + satisfaction score + sentiment).\n  - `tag_it(text_dict)` — calls `ChatGroq` and returns tags as CSV text.\n  - `analysis_report(text_dict)` — returns a long-form analysis of all reviews.\n  - `suggested_improvements(text_dict)` — returns actionable improvements.\n\n- `templates/` — Minimal HTML templates for the UI and error pages. A friendly about page (`safa.html`) contains contact information for the author.\n\n- `Dockerfile` — Prepares system deps for `pandas`/`numpy`, installs Python requirements and runs `app.py`.\n\n- `requirements.txt` — List of dependencies (Flask, pandas, numpy, langchain-core, langchain-groq, groq, openpyxl, etc.).\n\n---\n\n## 8. How it works — high-level flow\n\n1. User uploads an Excel file (`/upload`). The file is saved as `uploads/stored_excel_file.xlsx`.\n2. `process_excel()` reads the Excel and extracts the `Text` column into a dictionary (`material`) keyed by index.\n3. `/dashboard` calls `summarize(material)` and `tag_it(material)`. Those functions are expected to return **raw CSV text** that the code parses into DataFrames.\n4. `/analysis` and `/suggest` call `analysis_report(material)` and `suggested_improvements(material)` respectively and render returned markdown/HTML.\n\nUnderlying LLM calls are executed through `langchain-groq`'s `ChatGroq` wrapper.\n\n---\n\n## 9. Important implementation notes \u0026 gotchas\n\n- **Column name expectations:** uploaded Excel must have `Text` and `Rating` columns (case sensitive) — otherwise the code will raise errors when trying to access these columns.\n\n- **Prompt inconsistency (actionable TODO):** the summarization prompt in `app_functions.py` contains **inconsistent** instructions about CSV column names (the prompt mentions both `Rating` and `Satisfaction Score` in different places). This can cause downstream parsing mismatches. Consider standardizing the prompt to a single header (e.g. `Index,Review,Rating,Sentiment`) and updating the code that parses the CSV accordingly.\n\n- **Environment keys required:** if the Groq keys (`summarize_key`, `tag_key`, etc.) are missing the ChatGroq calls will fail with authentication errors.\n\n- **Template/UI are minimal:** templates are plain HTML placeholders — you may want to improve UX (scripts, CSS) before production use.\n\n- **No license file present:** If you plan to reuse or publish, add a `LICENSE` file to clarify permissions.\n\n- **Uploads are stored on disk inside the container:** Uploaded files will stay in `uploads/` inside the running container. If running in Docker, consider mounting a persistent volume if you want data to survive container restarts.\n\n---\n\n## 10. Troubleshooting \u0026 common errors\n\n- `KeyError: 'Text'` or `KeyError: 'Rating'` — uploaded file doesn't contain expected columns. Check the Excel and column names.\n\n- LangChain / Groq errors — check that the environment variable for the corresponding key is set and that you have network access.\n\n- `ModuleNotFoundError` — ensure you installed the packages with `pip install -r requirements.txt` or used the Docker image.\n\n- If the UI shows empty tables, verify that the summarization/tagging functions returned properly-formatted CSV text and that `csv_text_to_dataframe()` successfully parsed it.\n\n---\n\n## 11. Contact\n\nThe project includes an about page with contact details for the creator. Use those to reach out if you need help or want collaboration.\n\n(Details are present in `templates/safa.html` — please use the repo contact entry responsibly.)\n\n---\n\n## 12. License\n\nNo `LICENSE` file was found in the repository. Add one if you want to make reuse / redistribution explicit.\n\n---\n\n### Final notes\n\nIf you want to skip all these and directly jump into the tool, refer the ready-to-use docker image at: [adithya7reddy/safa/](https://hub.docker.com/r/adithya7reddy/safa)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadithya2369%2Fsafa_public","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadithya2369%2Fsafa_public","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadithya2369%2Fsafa_public/lists"}