# Contributing to Medium-MCP Thank you for your interest in contributing to Medium-MCP! This document provides guidelines and instructions for contributing. ## ๐Ÿš€ Quick Start ### Prerequisites - Python 3.11+ - [uv](https://github.com/astral-sh/uv) (recommended) or pip - Git ### Setup Development Environment ```bash # Clone the repository git clone https://github.com/N1KH1LT0X1N/Medium-Agent.git cd Medium-Agent/Medium-MCP # Install dependencies with uv (recommended) uv sync --dev # Or with pip pip install -e ".[dev]" # Install pre-commit hooks pre-commit install # Install Playwright browsers playwright install chromium ``` ## ๐Ÿ“‹ Development Workflow ### 1. Create a Branch ```bash git checkout -b feature/your-feature-name # or git checkout -b fix/your-bug-fix ``` ### 2. Make Changes - Write clean, typed Python code - Follow the existing code style - Add tests for new functionality - Update documentation as needed ### 3. Run Quality Checks ```bash # Format code ruff format . # Lint code ruff check . --fix # Type check mypy src/ # Run tests pytest tests/unit/ -v pytest tests/integration/ -v # Run all pre-commit hooks pre-commit run --all-files ``` ### 4. Commit Changes We use [Conventional Commits](https://www.conventionalcommits.org/): ```bash # Feature git commit -m "feat: add batch scraping progress bar" # Bug fix git commit -m "fix: handle rate limit in GraphQL tier" # Documentation git commit -m "docs: update API reference" # Refactoring git commit -m "refactor: extract URL resolver to separate module" ``` ### 5. Submit Pull Request - Push your branch and create a PR - Fill out the PR template - Wait for CI checks to pass - Address review feedback ## ๐Ÿงช Testing ### Test Structure ``` tests/ โ”œโ”€โ”€ unit/ # Fast, isolated tests โ”œโ”€โ”€ integration/ # Tests with mocked services โ”œโ”€โ”€ e2e/ # Browser-based tests โ””โ”€โ”€ fixtures/ # Test data files ``` ### Running Tests ```bash # All tests pytest # Unit tests only pytest tests/unit/ -v # With coverage pytest --cov=src --cov-report=html # Skip slow tests pytest -m "not slow" # Single test file pytest tests/unit/test_url_resolver.py -v ``` ### Writing Tests ```python import pytest from src.url_resolver import resolve_medium_url class TestURLResolver: @pytest.mark.asyncio async def test_valid_medium_url(self): result = await resolve_medium_url("https://medium.com/@user/title-abc123") assert "abc123" in result @pytest.mark.parametrize("url,expected", [ ("https://medium.com/p/abc123", "abc123"), ("https://towardsdatascience.com/title-xyz789", "xyz789"), ]) async def test_various_formats(self, url, expected): result = await resolve_medium_url(url) assert expected in result ``` ## ๐Ÿ“ Code Style ### Type Hints All functions must have type hints (mypy strict mode): ```python from typing import Optional from src.types import ArticleMetadata async def scrape_article( url: str, force_refresh: bool = False, ) -> ArticleMetadata: """Scrape article and return metadata.""" ... ``` ### Docstrings Use Google-style docstrings: ```python def extract_post_id(url: str) -> str | None: """ Extract Medium post ID from URL. Args: url: Full Medium article URL Returns: 12-character hexadecimal post ID, or None if not found Raises: ValueError: If URL is malformed """ ``` ### Imports Use ruff's isort rules (automatically handled): ```python # Standard library import asyncio from pathlib import Path # Third party import httpx from pydantic import BaseModel # Local from src.types import ArticleMetadata from src.constants import DEFAULT_TIMEOUT ``` ## ๐Ÿ—๏ธ Architecture ### File Structure ``` src/ โ”œโ”€โ”€ types.py # Type definitions (TypedDict, Enum) โ”œโ”€โ”€ constants.py # Magic numbers & config values โ”œโ”€โ”€ http_pool.py # Connection pooling โ”œโ”€โ”€ service.py # Main scraper service โ”œโ”€โ”€ server.py # MCP server (will be split) โ””โ”€โ”€ ... ``` ### Key Principles 1. **Type Safety**: Use TypedDict over Dict[str, Any] 2. **Constants**: No magic numbers in code 3. **Connection Pooling**: Use http_pool for all HTTP requests 4. **Error Handling**: Use custom exceptions from error_handling.py 5. **Logging**: Use structlog for structured logging ## ๐Ÿ› Reporting Issues ### Bug Reports Include: - Python version - OS and version - Steps to reproduce - Expected vs actual behavior - Error messages/tracebacks ### Feature Requests Include: - Use case description - Proposed solution - Alternatives considered ## ๐Ÿ“š Resources - [Project README](README.md) - [Implementation Plan](docs/IMPLEMENTATION_PLAN.md) - [MCP Specification](https://modelcontextprotocol.io/) - [FastMCP Documentation](https://gofastmcp.com/) ## ๐Ÿ“œ License By contributing, you agree that your contributions will be licensed under the MIT License.