{"id":31199948,"url":"https://github.com/hnthap/cat-or-dog","last_synced_at":"2026-04-14T05:31:21.899Z","repository":{"id":310135943,"uuid":"1038499990","full_name":"hnthap/cat-or-dog","owner":"hnthap","description":"An End-to-end AI Application classifying images as either a cat or a dog. The project leverages OpenVINO Model Server, a Node.js backend, and a React-based frontend.","archived":false,"fork":false,"pushed_at":"2025-08-16T23:13:02.000Z","size":14903,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-20T10:48:38.852Z","etag":null,"topics":["axios","docker","docker-compose","express","full-stack","image-classification","image-preprocessing","javascript","machine-learning","model-deployment","model-inference","nodejs","react","rest-api","self-host","sharp","typescript","vite","website"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hnthap.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2025-08-15T10:09:42.000Z","updated_at":"2025-09-08T23:23:13.000Z","dependencies_parsed_at":"2025-08-16T01:38:34.813Z","dependency_job_id":null,"html_url":"https://github.com/hnthap/cat-or-dog","commit_stats":null,"previous_names":["hnthap/cat-or-dog"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hnthap/cat-or-dog","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hnthap%2Fcat-or-dog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hnthap%2Fcat-or-dog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hnthap%2Fcat-or-dog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hnthap%2Fcat-or-dog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hnthap","download_url":"https://codeload.github.com/hnthap/cat-or-dog/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hnthap%2Fcat-or-dog/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31784251,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T02:24:21.117Z","status":"ssl_error","status_checked_at":"2026-04-14T02:24:20.627Z","response_time":153,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["axios","docker","docker-compose","express","full-stack","image-classification","image-preprocessing","javascript","machine-learning","model-deployment","model-inference","nodejs","react","rest-api","self-host","sharp","typescript","vite","website"],"created_at":"2025-09-20T10:48:32.637Z","updated_at":"2026-04-14T05:31:21.894Z","avatar_url":"https://github.com/hnthap.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Screenshot](./image.png)\n\n# **Cat or Dog?**\n\nA web application that uses a machine learning model to classify images as either a cat or a dog. The project leverages OpenVINO Model Server (OVMS) for inference, a Node.js backend for preprocessing and API handling, and a React-based frontend for user interaction.\n\nThe AI model used in this project was trained and evaluated using the code from the [Cat-Dog Classification](https://github.com/hnthap/cat-dog-classification) repository. \n\n## **Table of Contents**\n\n1. [Features](#features)\n2. [Tech Stack](#tech-stack)\n3. **[🔰 Getting Started](#-getting-started)**\n4. [Project Structure](#project-structure)\n5. [Endpoints](#endpoints)\n6. **[⚙️ Development](#-development)**\n7. [Testing](#testing)\n8. **[⭐ Future Improvements](#-future-improvements)**\n9. [Contributing](#contributing)\n10. [License](#license)\n11. [Acknowledgments](#acknowledgments)\n\n---- \n\n## **Features**\n\n- Upload an image to determine the probability of it being a cat or dog.\n- Real-time image preprocessing and inference using OpenVINO Model Server.\n- Responsive React frontend for seamless user experience.\n- Scalable backend with image validation and preprocessing.\n- Dockerized deployment for easy setup and portability.\n\n----\n\n## **Tech Stack**\n\n### **Frontend**\n\n- **React**: Built with TypeScript for type safety.\n- **Axios**: For making API requests to the backend.\n- **Vite**: For fast development and optimized builds.\n\n### **Backend**\n\n- **Node.js**: Express-based server for handling API requests.\n- **Multer**: For handling image uploads.\n- **Sharp**: For image preprocessing.\n- **Fetch**: For communicating with the OpenVINO Model Server.\n\n### **Machine Learning**\n\n- **OpenVINO Model Server (OVMS)**: Serves the pre-trained model for inference.\n\n### **Deployment**\n\n- **Docker**: Multi-container setup using `docker-compose` for the frontend, backend, and model server.\n- **Nginx**: Serves the static frontend files.\n\n----\n\n## **🔰 Getting Started**\n\n### **Prerequisites**\n\n- Docker and Docker Compose installed on your machine.\n- Node.js (if running locally without Docker).\n\n### **Setup**\n\n1. **Clone the Repository**:\n   ```bash\n   git clone https://github.com/hnthap/cat-or-dog.git\n   cd cat-or-dog\n   ```\n\n2. **Environment Variables**:\n   Create a `.env` file in the [backend](./backend/) directory and configure the following variables:\n   ```env\n   OVMS_HOSTNAME=model-server\n   OVMS_PORT=8000\n   FRONTEND_ORIGIN=http://localhost:3000\n   BACKEND_API_INFER_URL=http://localhost:3001/v1/infer\n   ```\n   Notes that `FRONTEND_ORIGIN` and `BACKEND_API_INFER_URL` are currently set for development. Change them to appropriate values in production.\n\n3. **Run with Docker Compose**:\n   ```bash\n   docker-compose up --build\n   ```\n   This will start:\n   - OpenVINO Model Server on `http://localhost:8000`\n   - Backend server on `http://localhost:3001`\n   - Frontend on `http://localhost:3000`\n\n4. **Access the Application**:\n   Open your browser and navigate to `http://localhost:3000`.\n\n----\n\n## **Project Structure**\n\n### **Frontend**\n\n- **Path**: [vite-client/](./vite-client/)\n- **Key Files**:\n  - [App.tsx](./vite-client/src/App.tsx): Main React component handling file uploads and predictions.\n  - [components/](./vite-client/src/components/): Reusable UI components like [`Header`](./vite-client/src/components/Header/Header.tsx), [`ImageCard`](./vite-client/src/components/ImageCard/ImageCard.tsx), and [`FileUploader`](./vite-client/src/components/FileUploader/FileUploader.tsx).\n  - [Dockerfile](./vite-client/Dockerfile): Dockerfile for the frontend service.\n\n### **Backend**\n\n- **Path**: [backend/](./backend/)\n- **Key Files**:\n  - [server.js](./backend/server.js): Express server handling image uploads, preprocessing, and inference.\n  - [Dockerfile](./backend/Dockerfile): Dockerfile for the backend service.\n\n### **Model Server**\n\n- **Path**: [models/](./models/)\n- **Key Files**:\n  - Pre-trained model files for the \"Cat or Dog\" classification.\n\n### **Docker Compose**\n\n- **Path**: [docker-compose.yaml](./docker-compose.yaml)\n- **Purpose**: Orchestrates the frontend, backend, and model server containers.\n\n----\n\n## **Endpoints**\n\n### **Backend API**\n- **POST /v1/infer**\n  - **Description**: Accepts an image file and returns the probability of it being a cat, denotes $p\\%$. The probability of it being a dog is $100\\% - p\\%$.\n  - **Request**:\n    - `Content-Type: multipart/form-data`\n    - Body: `{ image: \u003cfile\u003e }`\n  - **Response**:\n    ```json\n    {\n      \"cat\": 95.3\n    }\n    ```\n\n----\n\n## **⚙️ Development**\n\n### **Frontend**\n\n1. Navigate to the [vite-client](./vite-client/) directory:\n   ```bash\n   cd vite-client\n   ```\n2. Install dependencies:\n   ```bash\n   npm install\n   ```\n3. Start the development server:\n   ```bash\n   npm run dev\n   ```\n\n### **Backend**\n\n1. Navigate to the [backend](./backend/) directory:\n   ```bash\n   cd backend\n   ```\n2. Install dependencies:\n   ```bash\n   npm install\n   ```\n3. Start the server:\n   ```bash\n   node server.js\n   ```\n\n----\n\n## **Testing**\n\n### **Frontend**\n\nFrontend tests are not yet available.\n\n\u003c!-- - Run unit tests (if implemented):\n  ```bash\n  npm test\n  ``` --\u003e\n\n### **Backend**\n- Test the `/v1/infer` endpoint using tools like Postman or cURL:\n  ```bash\n  curl -X POST -F \"image=@path/to/image.jpg\" http://localhost:3001/v1/infer\n  ```\n\n----\n\n## **⭐ Future Improvements**\n\n### **General**\n\n- [ ] Deploy a Live Demo\n- [ ] Log past activity\n- [ ] Apply NIST CFS 2.0\n\n### **Frontend**\n\n- [ ] Drag and Drop image into view\n- [ ] Use Toasts instead of alert()\n- [ ] Add tests\n\n### **Backend**\n\n- [x] Use dotenv-safe to manage environment variables\n- [ ] Use logging library instead of console.log\n- [ ] Use queue system to process requests asynchronously\n- [ ] Use express-validator or Joi to validate request data\n- [ ] Add rate limiting with express-rate-limit\n- [ ] Use ndarray for matrix operations in preprocess()\n- [ ] Add unit tests for critical functions like infer() and preprocess()\n- [ ] Mock OVMS responses for testing purposes, under different scenarios, e.g., success, failure, invalid response\n- [ ] Add API documentation using Swagger or Postman\n- [ ] Validate `OVMS_*` environment variables at startup\n- [ ] Remember to test preprocess() with edge cases, such as (1) extremely small or large images, (2) image with unsupported format, (3) corrupted image files\n- [ ] Make startup log message more descriptive, e.g., \"development\" or \"production\" mode, OVMS host and port, etc.\n\n----\n\n## **Contributing**\n\nContributions are welcome! Please fork the repository and submit a pull request with your changes.\n\n----\n\n## **License**\nThis project is licensed under the MIT License. See the [LICENSE](./LICENSE) file for details.\n\n----\n\n## **Acknowledgments**\n\n- [OpenVINO Model Server](https://github.com/openvinotoolkit/model_server)\n- [Sharp](https://sharp.pixelplumbing.com/)\n- [Vite](https://vitejs.dev/)\n\n----","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhnthap%2Fcat-or-dog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhnthap%2Fcat-or-dog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhnthap%2Fcat-or-dog/lists"}