AI-Driven Marketplace for Industrial Circular Economy — Terminal UI
Project description
CircuLink Terminal
AI-Driven Marketplace for Industrial Circular Economy
A production-quality Python TUI (Terminal User Interface) that connects industrial buyers and sellers of waste materials, by-products, and recyclables using intelligent fuzzy matching, real-time GSTIN compliance, and Gemini 2.5 Flash AI reasoning.
Features
| Feature | Detail |
|---|---|
| GSTIN-gated KYC | Full 15-character GSTIN regex validation with Indian state-code lookup |
| AI Byproduct Prediction | Seller describes a process → Gemini 2.5 Flash predicts likely marketable byproducts |
| Hazardous Screening | 57-substance database (CAS + name); CAS match → exact → substring → RapidFuzz ≥85 — blocked listings never appear in search |
| Intelligent Search | Buyer enters a query → Gemini expands synonyms → RapidFuzz ensemble scoring → ranked results |
| Weighted Scoring | final_score = 0.7 × fuzzy_score + 0.3 × location_score |
| Location Proximity | Haversine distance + exponential decay; 100+ Indian industrial cities pre-geocoded |
| Persistent Storage | ~/.circularlink/ flat-JSON store; JSONL audit trail for every LLM call |
| Full TUI | Rich color scheme, sidebar navigation, modal dialogs — zero browser required |
Quick Start
pip install circularlink
circularlink
From source (editable install)
git clone https://github.com/your-org/circularlink.git
cd circularlink
pip install -e .
circularlink
Requires Python 3.11+.
First Run
- On launch you will see the Welcome / Login screen.
- Switch to the Register tab.
- Enter your company details — GSTIN is validated live.
- Paste your Google AI Studio API key (from aistudio.google.com).
- Register → you enter the main application.
Subsequent launches auto-restore your session via ~/.circularlink/config.json.
💡 Need test data? See SAMPLE_DATA.md for ready-to-use company credentials and testing scenarios.
Navigation
| Key | Screen |
|---|---|
F1 |
Dashboard — stats, recent matches, LLM audit log |
F2 |
Buy: Intelligent Sourcing — search / browse / history |
F3 |
Sell: Inventory — AI scan, manual add, hazard status |
F4 |
KYC / Settings — edit profile, change API key, logout |
Ctrl+Q |
Quit |
Architecture
src/circularlink/
├── app.py # Root App — LoginEvent, LogoutEvent, screen routing
├── __main__.py # CLI entry point → circularlink
├── styles.tcss # Textual CSS — Industrial Earth & Tech palette
│
├── core/
│ ├── gstin.py # GSTIN regex validator + state-code lookup
│ ├── geo.py # City geocoding, haversine, location scoring
│ ├── hazard.py # 4-strategy hazardous material checker
│ ├── matcher.py # FuzzyMatcher: ensemble NLP + weighted geo scoring
│ └── gemini_agent.py # Gemini 2.5 Flash: byproduct prediction + keyword expansion
│
├── storage/
│ └── db.py # JSON persistence layer (companies, products, matches, logs)
│
├── screens/
│ ├── welcome.py # Login + Registration + live GSTIN validation
│ ├── dashboard.py # F1 — stats, match table, LLM log
│ ├── buyer.py # F2 — search, Gemini expansion, ranked results
│ ├── seller.py # F3 — AI byproduct scan, hazard check, inventory
│ ├── kyc.py # F4 — profile management, logout, account delete
│ └── modals.py # MessageModal, ConfirmModal, AddProductModal, SearchModal
│
└── data/
└── hazardous.csv # 57 hazardous substances (CAS + name + UN number)
Scoring Formula
$$\text{final_score} = 0.7 \times \text{fuzzy_score} + 0.3 \times \text{location_score}$$
- fuzzy_score = ensemble average of RapidFuzz
token_set_ratio,token_sort_ratio,partial_ratioacross product name and description - location_score = $e^{-d / (R/5)}$ where $d$ is Haversine distance in km and $R$ is
max_radius_km(default 2000 km)
Hazard Check Strategy (defence-in-depth)
- CAS number regex match against CSV
- Exact name match (case-insensitive)
- Substring containment (both directions)
- RapidFuzz
token_set_ratio≥ 85
Any hit → product status set to blocked; never returned in buyer search.
Environment Variables
| Variable | Purpose |
|---|---|
GOOGLE_API_KEY |
Fallback API key if none stored in DB |
Recommended: set key via the KYC / Settings screen (stored locally, never transmitted outside Gemini API calls).
Storage
All data is stored under ~/.circularlink/:
~/.circularlink/
├── config.json # api_key, current_company_id
├── companies.json # Registered companies
├── products.json # Product listings (approved / blocked / pending)
├── matches.json # Saved search results
└── llm_logs/
└── YYYY-MM-DD.jsonl # Append-only Gemini call audit log
Dependencies
| Package | Version | Purpose |
|---|---|---|
textual |
≥0.80.0 | TUI framework |
google-generativeai |
≥0.8.0 | Gemini 2.5 Flash API |
rapidfuzz |
≥3.9.0 | Fuzzy NLP matching |
rich |
≥13.7.0 | Terminal rendering |
geopy |
≥2.4.0 | Geocoding utilities |
Color Scheme
| Role | Hex | Usage |
|---|---|---|
| Background Deep | #1A1B26 |
Screen background |
| Background Panel | #24253A |
Sidebar, cards |
| Seller / Red | #E06C75 |
Seller UI, warnings |
| Buyer / Green | #98C379 |
Buyer UI, success |
| AI / Blue | #61AFEF |
Gemini highlights |
| Hazard / Amber | #D19A66 |
Hazard banners |
| Accent / Purple | #C678DD |
Hotkeys, accents |
Publishing to PyPI
pip install build twine
python -m build
twine upload dist/*
License
MIT — see LICENSE for details.
Acknowledgements
Built with Textual by Textualize, Google Generative AI, and RapidFuzz.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file circularlink-1.0.0.tar.gz.
File metadata
- Download URL: circularlink-1.0.0.tar.gz
- Upload date:
- Size: 44.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8e4534dd8a2a70633d3f68c632a4bad75376e7b2e7ed43628df48a25a0706dfd
|
|
| MD5 |
381aa7b8f3042df3df6ee9efd1101357
|
|
| BLAKE2b-256 |
4d45cc93edcb796e29aa6f7653ca071255f423d47a2edfe3e6be8d98a4b7b373
|
File details
Details for the file circularlink-1.0.0-py3-none-any.whl.
File metadata
- Download URL: circularlink-1.0.0-py3-none-any.whl
- Upload date:
- Size: 50.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
19e79ddf6f9a9f896fbac0e212a4cb56dc2fc431f44f785f875b2856ad463d75
|
|
| MD5 |
be961fde8890491af8529c60bede737a
|
|
| BLAKE2b-256 |
34f65efcf57f9364f3721604902ffbdaaf9219d918c4b41986dd1a931eeaa1d8
|