AI-Powered Pharmaceutical Inventory Management & Sales Analytics Platform
An industrial-grade inventory management system combining real-time stock tracking, interactive sales analytics, and XGBoost-based stockout prediction to optimize pharmaceutical supply chains.
Real-time inventory metrics and color-coded stock levels across 33 medicines.

View and edit inventory with ML-predicted Days_to_Stockout for every medicine.
| View Inventory | Manage Inventory |
|---|---|
![]() |
|
![]() |
|
Shopping cart with live stock validation and automatic inventory deduction.

Interactive filtering by date, month, or year — switch between bar and line chart views.
| Bar Chart View | Line Chart View |
|---|---|
![]() |
|
![]() |
|
Per-medicine details: ATC code, uses, cautions, dosage, alternatives, and live stock count.

Medicines grouped by supplier with stock-level visualization.

- Overview
- Architecture
- Tech Stack
- Key Features
- Getting Started
- Project Structure
- Database Schema
- Machine Learning
- Security
- Testing
- Docker Deployment
- Contributing
- Author
PharmaStock Optimizer addresses a critical challenge in pharmaceutical retail — predicting when medicines will go out of stock before it happens. Traditional inventory systems rely on static reorder points, but demand for medicines varies by season, external factors, and trends.
This platform integrates XGBoost regression models trained on 33,000+ historical sales records to dynamically predict stockout timelines, enabling pharmacies to:
- 🎯 Proactively reorder before critical shortages
- 📉 Reduce wastage from overstocking perishable medicines
- 📊 Analyze sales trends with interactive, filterable visualizations
- 🏢 Manage supplier relationships with per-supplier medicine mappings
┌──────────────────────────────────────────────────────────────┐
│ Streamlit UI (app.py) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐ ┌──────┐ │
│ │Dashboard │ │Inventory │ │ Sales │ │Supplier│ │Meds │ │
│ │ Page │ │ Page │ │ Page │ │ Page │ │ Page │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └───┬────┘ └──┬───┘ │
├───────┼────────────┼────────────┼───────────┼─────────┼──────┤
│ │ Service Layer (services/) │ │ │
│ ┌────▼──────┐ ┌───▼─────┐ ┌────▼─────┐ ┌───▼────┐ │ │
│ │ Inventory │ │ Sales │ │ Orders │ │Supplier│ │ │
│ │ Service │ │ Service │ │ Service │ │Service │ │ │
│ └────┬──────┘ └────┬────┘ └────┬─────┘ └───┬────┘ │ │
├───────┼────────────┼────────────┼───────────┼─────────┼──────┤
│ │ Data Layer │ │ │
│ ┌────▼────────────▼────────────▼───────────▼────┐ ┌──▼───┐ │
│ │ SQLAlchemy ORM (database/) │ │ JSON │ │
│ │ Models: User │ Medicine │ Inventory │ Sale │ │ Data │ │
│ └──────────────────┬────────────────────────────┘ └──────┘ │
│ │ │
│ ┌──────────────────▼──────────────────────────────────┐ │
│ │ Cross-Cutting Concerns │ │
│ │ Auth (bcrypt+RBAC) │ ML (XGBoost) │ Logging │ │
│ └─────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
| Pattern | Implementation |
|---|---|
| Layered Architecture | UI → Service → ORM → Database |
| Repository Pattern | Service classes abstract all data access |
| Dependency Injection | SQLAlchemy sessions injected into services |
| Configuration as Code | Pydantic BaseSettings with .env override |
| Context Manager | get_session() handles commit/rollback/close |
| Layer | Technology | Purpose |
|---|---|---|
| Frontend | Streamlit | Interactive web UI |
| Visualization | Plotly Express | Interactive charts |
| ORM | SQLAlchemy 2.0 | Database abstraction |
| Database | SQLite (WAL mode) | Relational storage |
| Validation | Pydantic v2 | Input/config validation |
| Machine Learning | XGBoost | Stockout forecasting |
| Authentication | bcrypt | Salted password hashing |
| Configuration | pydantic-settings | Environment management |
| Testing | pytest | Unit test suite |
| Containerization | Docker | Production deployment |
Real-time inventory overview with color-coded stock charts and sidebar metrics (total medicines, low stock, expired).
CRUD operations with AI-powered stockout prediction on every update.
Shopping cart with cumulative stock validation and automatic inventory deduction.
Filter by date / month / year with interactive bar and line charts across 33,000+ sales records.
View medicines grouped by supplier with stock visualizations.
33 medicines with ATC codes, dosage, cautions, alternatives, and real-time stock display.
bcrypt hashing, role-based access (admin/user), session timeout, email recovery.
- Python 3.10+
- pip package manager
# Clone the repository
git clone https://github.com/Suresh-Note/PharmaStock_Optimizer.git
cd PharmaStock_Optimizer/pharma_stock
# Install dependencies
pip install -r requirements.txt
# Configure environment
cp .env.example .env
# Edit .env with your SMTP credentialsSMTP_EMAIL=your_email@gmail.com
SMTP_PASSWORD=your_gmail_app_password# Run the modular app
streamlit run app.py
# Or run the legacy single-file version
streamlit run PharmaStock.pypython -m pytest tests/ -vPharmaStock_Optimizer/
├── docs/
│ └── screenshots/ # UI screenshots for documentation
│
└── pharma_stock/
├── app.py # Entry point (thin router)
├── config.py # Centralized Pydantic settings
├── PharmaStock.py # Legacy single-file version
│
├── database/ # Data access layer
│ ├── connection.py # SQLAlchemy engine + session factory
│ └── models.py # ORM models (User, Medicine, Inventory, Sale)
│
├── auth/ # Authentication module
│ ├── security.py # bcrypt hashing + session management
│ ├── email.py # SMTP email service
│ └── service.py # Auth orchestration (register/login/delete)
│
├── services/ # Business logic layer
│ ├── inventory.py # Inventory CRUD + summary
│ ├── sales.py # Sales filtering + queries
│ ├── orders.py # Cart management + order processing
│ └── suppliers.py # Supplier-medicine mappings
│
├── ml/ # Machine learning pipeline
│ └── forecasting.py # XGBoost training + stockout prediction
│
├── pages_ui/ # Streamlit page modules
│ ├── dashboard.py # Dashboard view
│ ├── inventory_page.py # Inventory management
│ ├── sales_page.py # Sales analytics
│ ├── medicines_page.py # Medicine reference
│ └── suppliers_page.py # Supplier view
│
├── utils/ # Cross-cutting utilities
│ ├── logger.py # Structured logging
│ ├── exceptions.py # Custom exception hierarchy
│ └── validators.py # Pydantic input schemas
│
├── data/
│ ├── medicines_info.json # Medicine reference data
│ └── expanded_sales_data.csv # Historical sales dataset (33K rows)
│
├── tests/ # pytest test suite (24 tests)
│ ├── conftest.py # Fixtures (in-memory DB, sample data)
│ ├── test_auth.py # Auth service tests (9 tests)
│ ├── test_inventory.py # Inventory CRUD tests (9 tests)
│ └── test_forecasting.py # ML prediction tests (4 tests)
│
├── Dockerfile # Production container
├── docker-compose.yml # Container orchestration
├── requirements.txt # Python dependencies
└── .env # Environment secrets (not committed)
| Column | Type | Description |
|---|---|---|
| Medicine_Name | TEXT (PK) | Medicine identifier |
| ATC_Code | TEXT | ATC classification |
| Stock_Available | INTEGER | Current units in stock |
| Price_per_Unit | REAL | Current price |
| Reorder_Level | INTEGER | Low-stock threshold |
| Days_to_Stockout | INTEGER | ML-predicted days |
| Expiry_Date | DATE | Batch expiry |
| Column | Type | Description |
|---|---|---|
| Date | TEXT | Sale date (YYYY-Mon-DD) |
| Month | TEXT | Full month name |
| Year | INTEGER | Sale year |
| Medicine_Name | TEXT | Medicine identifier |
| Stock_Sold | INTEGER | Units sold |
| External_Factor | TEXT | Demand factor |
| Column | Type | Description |
|---|---|---|
| username | TEXT (PK) | Unique identifier |
| TEXT | Recovery email | |
| password | TEXT | bcrypt hash |
| role | TEXT | "admin" or "user" |
| created_at | DATETIME | Registration timestamp |
Per-medicine regression models predict daily sales volume:
Input: Day index (days since first recorded sale)
Output: Predicted units sold per day
Model: XGBRegressor (100 estimators, squared error)
Process:
- Train one model per medicine from historical sales data
- Starting from current stock, iterate day-by-day subtracting predicted sales
- Day count when stock reaches zero = Days to Stockout
Safeguards:
- Models cached with
@st.cache_resource(1-hour TTL) - 365-day iteration cap prevents infinite loops
- Negative predictions clamped to zero
| Feature | Implementation |
|---|---|
| Password Hashing | bcrypt with configurable rounds (default: 12) |
| RBAC | Admin/user roles stored in database |
| Session Timeout | Configurable expiry (default: 30 minutes) |
| Credential Storage | .env file, excluded from Git |
| SQL Injection | SQLAlchemy parameterized queries |
| Custom Exceptions | Structured error hierarchy (never leaks internals) |
24 tests covering 3 modules:
| Module | Tests | Coverage |
|---|---|---|
test_auth.py |
9 | Password hashing, register, login, delete, RBAC |
test_inventory.py |
9 | CRUD, stock deduction, summary, properties |
test_forecasting.py |
4 | Bounds, clamping, mock predictions |
python -m pytest tests/ -v
# ======================= 24 passed in 8.91s ========================Tests use in-memory SQLite databases — no effect on production data.
# Build and run
docker-compose up --build
# Or manually
docker build -t pharmastock .
docker run -p 8501:8501 --env-file .env pharmastockThe container includes a health check endpoint at /_stcore/health.
- Fork the repository
- Create a feature branch (
git checkout -b feature/your-feature) - Run tests (
python -m pytest tests/ -v) - Commit changes (
git commit -m 'Add your feature') - Push and open a Pull Request
Suresh Kanchamreddy
Built with ❤️ using Streamlit · SQLAlchemy · XGBoost · Pydantic · Docker



