{"id":36947158,"url":"https://github.com/jim-wyatt/msn-weather-wrapper","last_synced_at":"2026-04-16T00:04:27.433Z","repository":{"id":327491903,"uuid":"1108717201","full_name":"jim-wyatt/msn-weather-wrapper","owner":"jim-wyatt","description":"Modern Python weather API wrapper with Flask REST backend, React frontend, and Docker deployment. Automated CI/CD, security scanning, and semantic versioning.","archived":false,"fork":false,"pushed_at":"2025-12-22T20:01:44.000Z","size":3198,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-24T02:59:47.682Z","etag":null,"topics":["ci-cd","docker","flask","github-actions","msn-weather","python","react","rest-api","typescript","weather-api"],"latest_commit_sha":null,"homepage":"https://jim-wyatt.github.io/msn-weather-wrapper/","language":"Python","has_issues":false,"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/jim-wyatt.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":".github/SECURITY.md","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-12-02T20:28:43.000Z","updated_at":"2025-12-22T16:14:14.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jim-wyatt/msn-weather-wrapper","commit_stats":null,"previous_names":["jim-wyatt/msn-weather-wrapper"],"tags_count":44,"template":false,"template_full_name":null,"purl":"pkg:github/jim-wyatt/msn-weather-wrapper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jim-wyatt%2Fmsn-weather-wrapper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jim-wyatt%2Fmsn-weather-wrapper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jim-wyatt%2Fmsn-weather-wrapper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jim-wyatt%2Fmsn-weather-wrapper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jim-wyatt","download_url":"https://codeload.github.com/jim-wyatt/msn-weather-wrapper/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jim-wyatt%2Fmsn-weather-wrapper/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28384075,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-13T10:34:27.190Z","status":"ssl_error","status_checked_at":"2026-01-13T10:34:26.289Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":["ci-cd","docker","flask","github-actions","msn-weather","python","react","rest-api","typescript","weather-api"],"created_at":"2026-01-13T11:37:21.795Z","updated_at":"2026-04-12T19:09:06.025Z","avatar_url":"https://github.com/jim-wyatt.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MSN Weather Wrapper\n\n\u003e A modern, production-ready Python wrapper for MSN Weather with a FastAPI backend and Next.js frontend.\n\n[![CI/CD Pipeline](https://github.com/jim-wyatt/msn-weather-wrapper/actions/workflows/ci.yml/badge.svg)](https://github.com/jim-wyatt/msn-weather-wrapper/actions/workflows/ci.yml)\n[![PyPI version](https://img.shields.io/pypi/v/msn-weather-wrapper.svg)](https://pypi.org/project/msn-weather-wrapper/)\n[![Python](https://img.shields.io/pypi/pyversions/msn-weather-wrapper.svg)](https://pypi.org/project/msn-weather-wrapper/)\n[![License](https://img.shields.io/github/license/jim-wyatt/msn-weather-wrapper.svg)](LICENSE)\n[![Documentation](https://img.shields.io/badge/docs-GitHub%20Pages-blue)](https://jim-wyatt.github.io/msn-weather-wrapper/)\n[![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)\n[![Checked with mypy](https://img.shields.io/badge/mypy-checked-blue)](http://mypy-lang.org/)\n[![Container](https://img.shields.io/badge/container-ghcr.io-blue)](https://github.com/jim-wyatt/msn-weather-wrapper/pkgs/container/msn-weather-wrapper)\n\n---\n\n## Overview\n\nMSN Weather Wrapper is a comprehensive weather data solution featuring:\n\n- **Python Library** - Type-safe weather client with Pydantic models\n- **REST API** - Production-ready FastAPI service with built-in OpenAPI docs\n- **Web Frontend** - Modern Next.js 16 + React 19 + TypeScript 6\n- **Containerized** - Podman/Docker deployment with Gunicorn, Uvicorn workers, and Nginx\n\n**Technology Stack:**\n\n- **Backend**: Python 3.10+, FastAPI 0.115+, Pydantic 2.12+, Uvicorn, Gunicorn 23.0+\n- **Frontend**: Next.js 16, React 19.2, TypeScript 6+\n- **Testing**: pytest 9.0+, Playwright, 168 tests (128 backend, 40 frontend E2E) with 97% coverage\n- **Quality**: ruff 0.14+, mypy 1.19+, pre-commit hooks\n- **Security**: Bandit, Semgrep, pip-audit, Trivy, Grype, weekly automated scans\n- **Deployment**: Podman/Docker, Nginx, multi-stage builds\n\n---\n\n## Quick Start\n\n### 🚀 Containerized Deployment (Recommended)\n\n```bash\ngit clone https://github.com/jim-wyatt/msn-weather-wrapper.git\ncd msn-weather-wrapper\npodman-compose up -d\n# Access at http://localhost:8080\n```\n\n### 📦 Python Package\n\n```bash\npip install msn-weather-wrapper\n```\n\n```python\nfrom msn_weather_wrapper import WeatherClient, Location\n\nwith WeatherClient() as client:\n    location = Location(city=\"London\", country=\"UK\")\n    weather = client.get_weather(location)\n    print(f\"Temperature: {weather.temperature}°C\")\n```\n\n### 🧪 Development Environment\n\n```bash\n./dev.sh setup   # One-time setup\n./dev.sh start   # Start dev servers\n./dev.sh status  # Check health\n# Frontend: http://localhost:3000\n# API: http://localhost:5000\n# Health: http://localhost:5000/api/v1/health\n```\n\n### 🧭 Start Here If You're New\n\nIf you're learning the codebase, explore it in this order:\n\n1. `backend/msn_weather_wrapper/` — backend logic and the FastAPI app\n2. `frontend/` — the Next.js UI\n3. `tests/` — examples of expected behavior\n4. `scripts/` — helper commands for setup, reports, and deployment tasks\n\n\u003e A detailed walkthrough now lives in `docs/PROJECT_STRUCTURE.md`.\n\n---\n\n## Features\n\n- 🌤️ Weather data extraction from MSN Weather\n- 🌍 463+ cities worldwide with autocomplete\n- 🔌 RESTful API with comprehensive validation\n- 📚 **Interactive API docs** (Swagger UI at `/apidocs/`)\n- ⚛️ Modern web interface with React + TypeScript\n- 🚀 5-minute caching (90%+ faster repeated requests)\n- 🔒 Rate limiting (30 req/min per IP, 200/hr global)\n- 🛡️ Input validation \u0026 attack prevention (SQL injection, XSS, etc.)\n- 🔐 **Automated security scanning** (Bandit, Semgrep, Trivy, Grype)\n- 🔍 Type safety with mypy strict mode\n- 📋 SBOM generation for supply chain security\n- ♿ WCAG 2.1 Level AA accessible frontend\n- 🔄 **Modular CI/CD workflows** - Reusable, maintainable architecture\n- 🔄 **Optimized CI/CD** with Docker caching \u0026 conditional matrices\n- 🏷️ **Automated semantic versioning** - Every PR auto-publishes to PyPI\n\n---\n\n## Installation\n\n### Prerequisites\n\n- Python 3.10+\n- Node.js 24+ (for frontend development)\n- Podman or Docker (for containerized deployment)\n\n### From Source\n\n```bash\ngit clone https://github.com/jim-wyatt/msn-weather-wrapper.git\ncd msn-weather-wrapper\npython -m venv .venv\nsource .venv/bin/activate  # Windows: .venv\\Scripts\\activate\npip install -e \".[dev]\"\npre-commit install\n```\n\n---\n\n## Usage\n\n### Python Library\n\n```python\nfrom msn_weather_wrapper import WeatherClient, Location\n\nwith WeatherClient() as client:\n    location = Location(city=\"Seattle\", country=\"USA\")\n    weather = client.get_weather(location)\n\n    print(f\"Temperature: {weather.temperature}°C\")\n    print(f\"Condition: {weather.condition}\")\n    print(f\"Humidity: {weather.humidity}%\")\n```\n\n### REST API\n\n```bash\n# Development\npython api.py\n\n# Production\ngunicorn -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:5000 --workers 4 --timeout 120 api:app\n\n# GET request\ncurl \"http://localhost:5000/api/weather?city=London\u0026country=UK\"\n\n# POST request\ncurl -X POST http://localhost:5000/api/weather \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"city\": \"London\", \"country\": \"UK\"}'\n```\n\n### Web Frontend\n\n```bash\ncd frontend\nnpm install\nnpm run dev  # http://localhost:3000\n```\n\n**Features:** City autocomplete (463+ cities), temperature unit toggle (°C/°F), geolocation support, responsive design, WCAG 2.1 Level AA accessibility\n\n---\n\n## Development\n\n```bash\n# Setup \u0026 Run\n./dev.sh setup   # One-time setup\n./dev.sh start   # Start dev environment\n./dev.sh test    # Run tests\n./dev.sh logs    # View logs\n\n# Code Quality\nruff format .                    # Format\nruff check .                     # Lint\nmypy backend/msn_weather_wrapper     # Type check\npre-commit run --all-files       # Run all checks\n\n# Testing\npytest                           # All tests\npytest --cov=backend --cov-report=html  # With coverage\npytest tests/test_client.py -v   # Specific file\n```\n\n---\n\n## Deployment\n\n```bash\n# Podman/Docker Compose\npodman-compose up -d\npodman-compose logs -f\npodman-compose down\n\n# Standalone Container\npodman build -t msn-weather-wrapper .\npodman run -p 8080:80 msn-weather-wrapper\n```\n\n**Architecture:** Unified container (Python + Node.js), Nginx reverse proxy, Gunicorn with Uvicorn workers, and Kubernetes-ready health checks\n\n---\n\n## Documentation\n\n📚 [Full Documentation](https://jim-wyatt.github.io/msn-weather-wrapper/)\n\n- [API Reference](docs/API.md) - Complete REST API documentation\n- [Interactive Swagger UI](docs/SWAGGER.md) - Live API testing \u0026 exploration\n- [Development Guide](docs/DEVELOPMENT.md) - Setup \u0026 development workflow\n- [Testing Guide](docs/TESTING.md) - Test suite \u0026 coverage\n- [Security Guide](docs/SECURITY.md) - Security features \u0026 automated scanning\n- [SBOM Guide](docs/SYFT_GUIDE.md) - Software bill of materials\n- [Changelog](docs/CHANGELOG.md) - Version history\n\n---\n\n## Project Structure\n\n```text\nmsn-weather-wrapper/\n├── backend/msn_weather_wrapper/\n│   ├── api/                    # FastAPI app (main, routers, services, schemas)\n│   ├── client.py               # Core MSN weather client\n│   ├── models.py               # Shared Pydantic models\n│   └── exceptions.py           # Domain exceptions\n├── frontend/                   # React application\n├── tests/                      # Backend and integration tests\n├── scripts/                    # Dev, reporting, and deployment helpers\n├── infra/                      # Containers, compose files, and runtime config\n├── docs/                       # Docs and beginner walkthroughs\n├── api.py                      # Local API entrypoint\n├── dev.sh                      # Thin wrapper around `scripts/dev.sh`\n└── pyproject.toml              # Python project configuration\n```\n\n---\n\n## Contributing\n\nContributions are welcome! Please ensure:\n\n1. ✅ All tests pass: `pytest`\n2. 🎨 Code is formatted: `ruff format .`\n3. 🔍 Type checks pass: `mypy backend/`\n4. 🪝 Pre-commit hooks pass\n5. 📝 Documentation is updated\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.\n\n---\n\n## License\n\nMIT License - see [LICENSE](LICENSE) for details.\n\n---\n\n## Links\n\n- 📖 [Documentation](https://jim-wyatt.github.io/msn-weather-wrapper/)\n- 📦 [PyPI Package](https://pypi.org/project/msn-weather-wrapper/)\n- 🐛 [Issue Tracker](https://github.com/jim-wyatt/msn-weather-wrapper/issues)\n- 💬 [Discussions](https://github.com/jim-wyatt/msn-weather-wrapper/discussions)\n\n---\n\n## Disclaimer\n\nThis project is an unofficial wrapper for MSN Weather data and is provided for educational and personal use only. This software is not affiliated with, endorsed by, or officially connected to Microsoft Corporation or MSN Weather in any way.\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjim-wyatt%2Fmsn-weather-wrapper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjim-wyatt%2Fmsn-weather-wrapper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjim-wyatt%2Fmsn-weather-wrapper/lists"}