{"id":31581243,"url":"https://github.com/tsotetsi/pingwatch","last_synced_at":"2026-05-04T15:31:35.952Z","repository":{"id":318003920,"uuid":"1069644384","full_name":"tsotetsi/pingwatch","owner":"tsotetsi","description":"Light weight health endpoint for checking connectivity.","archived":false,"fork":false,"pushed_at":"2025-10-04T12:10:34.000Z","size":128,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-04T13:26:05.650Z","etag":null,"topics":["expo","expo-go","fastapi","pydantic-v2","react-native"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/tsotetsi.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-04T10:42:35.000Z","updated_at":"2025-10-04T12:12:12.000Z","dependencies_parsed_at":"2025-10-04T13:26:11.387Z","dependency_job_id":"bd7160d5-e1c7-4b49-a45f-c2846a224992","html_url":"https://github.com/tsotetsi/pingwatch","commit_stats":null,"previous_names":["tsotetsi/pingwatch"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/tsotetsi/pingwatch","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsotetsi%2Fpingwatch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsotetsi%2Fpingwatch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsotetsi%2Fpingwatch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsotetsi%2Fpingwatch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tsotetsi","download_url":"https://codeload.github.com/tsotetsi/pingwatch/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsotetsi%2Fpingwatch/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278526244,"owners_count":26001326,"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-05T02:00:06.059Z","response_time":54,"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":["expo","expo-go","fastapi","pydantic-v2","react-native"],"created_at":"2025-10-05T21:55:20.116Z","updated_at":"2025-10-05T21:55:26.774Z","avatar_url":"https://github.com/tsotetsi.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PingWatch 📡\n\n[![React Native](https://img.shields.io/badge/React%20Native-0.76-61dafb?style=for-the-badge\u0026logo=react\u0026logoColor=white)](https://reactnative.dev/)\n[![Expo](https://img.shields.io/badge/Expo-~54.0-000020?style=for-the-badge\u0026logo=expo\u0026logoColor=white)](https://expo.dev/)\n[![Docker](https://img.shields.io/badge/Docker-Ready-2496ED?style=for-the-badge\u0026logo=docker\u0026logoColor=white)](https://www.docker.com/)\n[![FastAPI](https://img.shields.io/badge/FastAPI-0.115-009688?style=for-the-badge\u0026logo=fastapi\u0026logoColor=white)](https://fastapi.tiangolo.com/)\n[![Pydantic](https://img.shields.io/badge/-Pydantic-464646?style=for-the-badge\u0026logo=Pydantic)](https://docs.pydantic.dev/latest/)\n[![Python](https://img.shields.io/badge/Python-3.12+-3776ab?style=for-the-badge\u0026logo=python\u0026logoColor=white)](https://www.python.org/)\n[![License](https://img.shields.io/badge/License-MIT-green?style=for-the-badge)](LICENSE)\n\n\u003e Real-time network connectivity monitoring with instant notifications. Never be caught off-guard by connection issues again.\n\n## ✨ Features\n\n- 🔄 **Real-time Monitoring** - Configurable ping intervals (5s to 60s).\n- 🔔 **Instant Notifications** - Immediate alerts on connection loss/restoration.\n- 📊 **Activity History** - Track recent pings with latency metrics.\n- 🎨 **Beautiful UI** - Modern dark theme with smooth animations.\n- 🔋 **Battery Efficient** - Optimized foreground service.\n- 📱 **Works Everywhere** - WiFi and mobile data (perfect for hotspot users).\n- 🚫 **No Invasive Permissions** - No location or storage access required.\n\n## 🏗️ Architecture\n\n### Frontend Stack\n- **React Native** - Cross-platform mobile framework.\n- **Expo SDK 54+** - Development and build tooling.\n- **Expo Notifications** - Push notification handling.\n- **NetInfo** - Network state detection.\n- **Task Manager** - Background task execution.\n\n### Backend Stack\n- **FastAPI** - High-performance async Python framework.\n- **Uvicorn** - ASGI server with performance enhancements.\n- **Pydantic** - Data validation.\n- **Python 3.12+** - Modern Python features.\n\n## 📦 Installation\n\n### Prerequisites\n- Node.js 18+ and npm/yarn\n- Python 3.12+\n- Expo CLI (`npm install -g expo-cli`)\n- iOS Simulator or Android Emulator (or physical device)\n\n### Backend Setup\n\n1. **Clone the repository**\n```bash\ngit clone https://github.com/tsotetsi/pingwatch.git\ncd pingwatch/backend\n```\n\n2. **Create virtual environment**\n```bash\npython -m venv venv\nsource venv/bin/activate  # On Windows: venv\\Scripts\\activate\n```\n\n3. **Install dependencies**\n```bash\npip install -r requirements/local.txt\n```\n\n4. **Run the server**\n```bash\nuvicorn src.main:app --reload --host 0.0.0.0 --port 8000\n```\n\nThe API will be available at `http://localhost:8000`\n\n**API Documentation:** `http://localhost:8000/docs`\n\n## 🐳 Docker Deployment\n\n### Prerequisites\n- Docker 28.5+\n- Docker Compose 2.39+\n\n### Quick Start with Docker\n\n1. **Clone the repository**\n```bash\ngit clone https://github.com/tsotetsi/pingwatch.git\ncd pingwatch\n```\n\n2. **Create environment file.**\n```bash\ncp .env.example .env\n# Edit .env with your configuration.\n```\n\n3. **Build and run.**\n```bash\ndocker compose up --build -d\n```\n\n4. **Verify it's working.**\n```bash\n# Check container status.\ndocker compose ps\n\n# View logs.\ndocker compose logs -f backend\n\n# Test the API.\ncurl http://localhost:8000/api/v1/health\n```\n\n**The API will be available at:**\n\n- **API**: http://localhost:8000\n- **Interactive docs**: http://localhost:8000/docs\n- **Health check**: http://localhost:8000/health\n\n**Common Docker Commands.**\n\n```bash\n# Stop services\n\ndocker compose down\n\n# Rebuild after code changes\ndocker compose up -d --build\n\n# View logs\ndocker compose logs -f backend\n\n# Execute commands in container\ndocker compose exec backend python --version\n\n# Run tests in container\ndocker compose exec backend pytest\n```\n\nProduction Deployment\nFor production, update your .env file:\n\n```env\nENVIRONMENT=production\nLOG_LEVEL=WARNING\nALLOWED_ORIGINS=https://yourdomain.com\n```\n\n**Then deploy:**\n\n```bash\ndocker compose up -d --build\n```\n\n# Secure Dependency Management\n\nThis project uses a security-first approach to Python dependency management with `pip-tools` and hash pinning to prevent supply chain attacks.\n\n## 🛡️ Security Features\n\n- **Hash verification**: All packages are verified against stored hashes during installation.\n- **Reproducible builds**: Exact same dependencies every time.\n- **Dependency separation**: Base, local, and production environments.\n- **Transitive dependency control**: All sub-dependencies are explicitly pinned.\n\n## 📁 Requirements Structure\n\n* requirements/\n\\\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;├── **base.in** # Source: Core dependencies with version ranges\n\\\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;├── **base.txt** # Generated: Locked versions with hashes\n\\\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;├── **local.in** # Source: Development tools\n\\\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;├── **local.txt** # Generated: Development environment\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\\\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;├── **production.in** # Source: Production-only packages\n\\\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;└── **production.txt** # Generated: Production environment\n\n\n* **README.md** # This documentation.\n\n\n## 🔄 Workflow\n\n### Adding a New Dependency\n\n1. **Add to the appropriate `.in` file**:\n```bash\necho \"new-package\u003e=1.0.0,\u003c2.0.0\" \u003e\u003e requirements/base.in\n```\n\n2. **Generate locked versions with hashes**:\n```bash\n./scripts/update-requirements.sh\n```\n\n3. **Test and commit both files**:\n```bash\ngit add requirements/base.in requirements/base.txt\ngit commit -m \"feat: add new-package dependency\"\n```\n****\n\n**Regular Security Updates(Monthly)**\n```bash\n# Update all dependencies to latest compatible versions.\n./scripts/update-requirements.sh\n\n# Test thoroughly, then commit updates.\ngit add requirements/*.txt\ngit commit -m \"chore: update dependencies for security\"\n```\n\n**Updating Specific Packages**\n```bash\n# Update a specific package and its dependencies.\npip-compile --upgrade-package fastapi --generate-hashes requirements/base.in -o requirements/base.txt\n\n# Update all packages in a file.\npip-compile --upgrade --generate-hashes requirements/base.in -o requirements/base.txt\n```\n\n**Development Setup**\n```bash\n# Install development dependencies (with hash verification).\npip install --require-hashes -r requirements/local.txt\n\n# Or for production-like environment.\npip install --require-hashes -r requirements/base.txt\n```\n\n🏗️ **Build Process**\nThe Docker build automatically enforces hash verification:\n\n```dockerfile\n# In Dockerfile - all installations require hashes\nRUN /opt/venv/bin/pip install --no-cache-dir --require-hashes -r /app/requirements/base.txt\n```\n\n### Frontend Setup\n\n1. **Navigate to frontend directory**\n```bash\ncd ../frontend\n```\n\n2. **Install dependencies**\n```bash\nnpm install\n# or\nyarn install\n```\n\n3. **Install Expo modules**\n```bash\nnpx expo install expo-notifications expo-task-manager expo-background-fetch @react-native-community/netinfo\n```\n\n4. **Update API URL**\nEdit `App.tsx` and update the `API_URL` constant:\n```typescript\nconst API_URL = 'https://your-server-url.com/ping';\n// For local testing: http://YOUR_LOCAL_IP:8000/ping\n```\n\n5. **Configure app.json**\n```json\n{\n  \"expo\": {\n    \"name\": \"PingWatch\",\n    \"slug\": \"pingwatch\",\n    \"version\": \"1.0.0\",\n    \"plugins\": [\n      [\n        \"expo-notifications\",\n        {\n          \"sounds\": []\n        }\n      ]\n    ],\n    \"android\": {\n      \"permissions\": [\n        \"FOREGROUND_SERVICE\",\n        \"WAKE_LOCK\",\n        \"POST_NOTIFICATIONS\"\n      ],\n      \"package\": \"com.yourcompany.pingwatch\"\n    },\n    \"ios\": {\n      \"bundleIdentifier\": \"com.yourcompany.pingwatch\",\n      \"infoPlist\": {\n        \"UIBackgroundModes\": [\"fetch\", \"remote-notification\"]\n      }\n    }\n  }\n}\n```\n\n6. **Start the app**\n```bash\nnpx expo start\n```\n\nPress `i` for iOS simulator or `a` for Android emulator.\n\n\n7. **Testing on the actual device(Androin)**\n\n- **Make sure you have turned on android debugging or USB mode.**\n- **If you are using USB debugging, make sure File transfer... or Transfer .. is selected. Not just charging**\n\nThen run the following command to check and connect your phone to your PC/Laptop:\n```bash\nadb devicesList of devices attached\n8a5517d1        device\n```\n\nyou should get something like:\n```bash\nList of devices attached\n1z1516r9        device  # (This is a random string for reference only.)\n```\n\n**For the best Native Development Experience(Recommended)**\n\nExpo Go is the perfect tool for learning, prototyping, and experimenting, but most production apps will convert to using development builds sooner rather than later.\n\nPlease see the (why) reason you should convert to development build: https://docs.expo.dev/develop/development-builds/introduction/\n\n**Run the native devlopment build(s)**\n\nThe following command will create prebuild packages for the provided operating system. \n\n```bash\n# For Andoid Operating System.\n\nnpx expo run:android\n\n# For iPhome Operating System.\n\nnpx expo run:ios\n\n# Note for ios, you need to have Xcode installed. \n\n- MacBook is not strictly required for App development.\n- Mac is required for App Store distribution.\n- Register for an Apple Developer program, you need  an iPhone\n  or iPad with Touch ID, Face ID, or a passcode, or a Mac with T2\n  Security Chip or Apple Silicon, to verify your identity during\n  the enrollment process.\n\n```\n\nHere is a snipper regarding having a free Apple Developer Account:\n\n**AI Overview**\nYes, you can create a free Apple Developer Account without a Mac, iPhone, or iPad by simply signing up with an existing Apple ID or creating a new one on their website, Apple Developer. This free account gives you access to Xcode, documentation, and the ability to test apps on your own devices, but it does not allow you to distribute apps on the App Store, which requires a paid membership. \n\n\n\n\n## 🚀 Usage\n\n1. **Start Monitoring**\n   - Launch the app.\n   - Tap \"Start Monitoring\" button.\n   - Grant notification permissions when prompted.\n\n2. **Configure Settings**\n   - Choose your preferred ping interval (5s, 10s, 30s, or 60s).\n   - Toggle auto-reconnect detection.\n   - *Note: Stop monitoring before changing intervals*.\n\n3. **Monitor Connection**\n   - Watch real-time status indicator.\n   - View ping history with latency.\n   - Receive instant notifications on connection changes.\n\n4. **Foreground Service**\n   - Persistent notification shows monitoring is active.\n   - App continues monitoring even when minimized.\n   - Swipe away notification to stop monitoring.\n\n## 📡 API Endpoints\n\n### `GET /ping`\nLightweight connectivity check endpoint.\n\n**Response:**\n```json\n{\n  \"status\": \"ok\",\n  \"timestamp\": \"2025-10-04T12:34:56.789Z\",\n  \"server_time\": 1728048896.789,\n  \"message\": \"pong\"\n}\n```\n\n### `GET /health`\nServer health check endpoint.\n\n**Response:**\n```json\n{\n  \"status\": \"healthy\",\n  \"timestamp\": \"2025-10-04T12:34:56.789Z\"\n}\n```\n\n### `GET /`\nAPI information endpoint.\n\n## 🧪 Testing\n\n### Backend Tests\n```bash\ncd backend\npytest tests/ -v --cov=app --cov-report=html\n```\n\n### Frontend Tests\n```bash\ncd frontend\nnpm test\n# or\nyarn test\n```\n\n### E2E Tests\n```bash\nnpm run test:e2e\n```\n\n## 📊 Code Coverage\n\n| Component | Coverage |\n|-----------|----------|\n| Backend API | ![Coverage](https://img.shields.io/badge/coverage-95%25-brightgreen) |\n| Frontend Components | ![Coverage](https://img.shields.io/badge/coverage-87%25-yellowgreen) |\n| Integration Tests | ![Coverage](https://img.shields.io/badge/coverage-80%25-yellow) |\n\n## 🔧 Configuration\n\n### Environment Variables (Backend)\n\nCreate a `.env` file in the backend directory:\n\n```env\n# Server Configuration\nHOST=0.0.0.0\nPORT=8000\nRELOAD=True\n\n# CORS Settings\nALLOWED_ORIGINS=*\n\n# Logging\nLOG_LEVEL=INFO\n```\n\n### App Configuration (Frontend)\n\nEdit constants in `App.js`:\n\n```typescript\nconst PING_INTERVAL = 10; // seconds\nconst API_URL = 'https://your-api.com/ping';\nconst PING_TIMEOUT = 5000; // milliseconds\n```\n\n## 📱 Building for Production\n\n### Android (APK/AAB)\n```bash\neas build --platform android\n```\n\n### iOS (IPA)\n```bash\neas build --platform ios\n```\n\n### Both Platforms\n```bash\neas build --platform all\n```\n\n*Note: Requires Expo EAS account. See [Expo docs](https://docs.expo.dev/build/introduction/) for setup.*\n\n## 🐛 Troubleshooting\n\n### Common Issues\n\n**Issue:** Notifications not showing\n- Ensure notification permissions are granted.\n- Check Android notification settings for the app.\n- Verify foreground service is running.\n\n**Issue:** Background monitoring stops\n- Enable \"Remove battery restrictions\" for the app.\n- Disable battery optimization for ConnectPulse.\n- Check if phone has aggressive battery management.\n\n**Issue:** Can't connect to backend\n- Verify backend is running.\n- Check API_URL is correct (use local IP, not localhost).\n- Ensure device and server are on same network (for local testing).\n- Check firewall settings.\n\n**Issue:** iOS background limitations\n- iOS restricts background fetch to ~15min intervals.\n- Use foreground service for real-time monitoring.\n- Keep app in foreground for best results\n\n## 🤝 Contributing\n\nContributions are welcome! Please follow these steps:\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\nPlease ensure:\n- Code follows existing style conventions.\n- Tests pass (`npm test` and `pytest`).\n- Documentation is updated.\n- Commit messages are clear and descriptive.\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## 👨‍💻 Author\n\n**Thapelo Tsotetsi**\n- GitHub: [@tsotetsi](https://github.com/tsotetsi)\n- LinkedIn: [Thapelo Tsotetsi](https://linkedin.com/in/tsotetsi-thapelo)\n\n## 🙏 Acknowledgments\n\n- Built with [React Native](https://reactnative.dev/)\n- Powered by [Expo](https://expo.dev/)\n- Backend with [FastAPI](https://fastapi.tiangolo.com/)\n- Icons from [Lucide React](https://lucide.dev/)\n\n## 📈 Roadmap\n\n- [ ] Multiple ping endpoints (fallback servers).\n- [ ] Bandwidth usage statistics.\n- [ ] Export ping history to CSV.\n- [ ] Dark/Light theme toggle.\n- [ ] Connection quality metrics.\n- [ ] Custom notification sounds.\n- [ ] Widget support (Android/iOS).\n- [ ] Speed test integration.\n- [ ] Historical data graphs\n\n## 💬 Support\n\nHaving issues? Please check the [Issues](https://github.com/tsotetsi/pingwatch/issues) page or create a new issue.\n\n---\n\n\u003cp align=\"center\"\u003eMade with ❤️ by developers who got tired of surprise connection drops.\u003c/p\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftsotetsi%2Fpingwatch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftsotetsi%2Fpingwatch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftsotetsi%2Fpingwatch/lists"}