From 02e69b6d3b12625e838038809542e3087d894c93 Mon Sep 17 00:00:00 2001 From: Nitzan Pomerantz <9297302+nitzpo@users.noreply.github.com> Date: Fri, 31 Oct 2025 19:02:33 +0200 Subject: [PATCH] Ran ruff format etc. --- CLAUDE.md | 27 ++++++++++ CONTRIBUTING.md | 59 +++++++++++++++++----- examples/investment_analysis.py | 2 +- examples/valuation.py | 4 +- tests/api_health/test_govmap_api_health.py | 6 +-- tests/test_govmap_client.py | 14 ++--- 6 files changed, 89 insertions(+), 23 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 9bbdfd4..4518e07 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -40,6 +40,33 @@ Nadlan-MCP is a Model Context Protocol (MCP) server that provides Israeli real e - Don't forget the virtualenv in venv/ +### Code Quality Workflow + +**IMPORTANT: Before making any commits, ensure code quality:** + +```bash +# Quick check - runs all PR checks locally +./check-quality.sh + +# Or manually: +ruff format . # Format code +ruff check . --fix # Fix lint issues +pytest tests/ -m "not api_health" -q # Run tests +ruff check . # Verify no issues remain +``` + +**For human developers using VSCode/Cursor:** +- Install Ruff extension (charliermarsh.ruff) +- Code is auto-formatted on save +- Lint errors shown inline +- `.vscode/settings.json` configures this automatically + +**For Claude Code:** +- Always run `ruff format .` before committing +- Always run `ruff check . --fix` to auto-fix issues +- Always run tests to verify no breakage +- Or use `./check-quality.sh` to run all checks at once + ### Running the Server ```bash diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7d06ac3..fcbc8f2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,7 +34,28 @@ pip install -r requirements.txt pip install -r requirements-dev.txt ``` -### 4. Verify Setup +### 4. Set Up IDE Integration (Recommended) + +**For VSCode/Cursor users:** + +The project includes `.vscode/settings.json` which automatically: +- Formats code on save with Ruff +- Shows lint errors inline +- Organizes imports automatically +- Runs tests with pytest + +**Install recommended extensions:** +1. Open VSCode/Cursor in the project directory +2. You'll be prompted to install recommended extensions +3. Install "Ruff" extension by charliermarsh + +**Benefits:** +- ✅ Automatic formatting on save +- ✅ Real-time lint errors +- ✅ Auto-fix on save +- ✅ No manual commands needed + +### 5. Verify Setup ```bash # Run tests @@ -43,6 +64,9 @@ pytest tests/ -m "not api_health" -q # Check code quality ruff check . ruff format --check . + +# Or use the quick check script +./check-quality.sh ``` ## Development Workflow @@ -59,21 +83,29 @@ git checkout -b fix/issue-description Follow the code style guidelines below. -### 3. Run Tests +**If using VSCode/Cursor with Ruff extension:** +- Code is automatically formatted on save +- Lint errors are shown inline +- Auto-fixes apply on save +- No manual commands needed! +**If not using IDE integration:** +- Run `./check-quality.sh` before committing +- Or run individual commands below + +### 3. Check Before Committing + +**Quick check (recommended):** ```bash -# Run fast tests -pytest tests/ -m "not api_health" -q - -# Run with coverage -pytest tests/ -m "not api_health" --cov=nadlan_mcp - -# Run specific test file -pytest tests/govmap/test_filters.py -v +./check-quality.sh ``` -### 4. Code Quality Checks +This script runs all checks that will run in the PR: +1. Ruff format check +2. Ruff linting +3. All tests +**Manual checks:** ```bash # Format code ruff format . @@ -81,11 +113,14 @@ ruff format . # Lint code ruff check . --fix +# Run tests +pytest tests/ -m "not api_health" -q + # Check remaining issues ruff check . ``` -### 5. Commit Changes +### 4. Commit Changes ```bash git add . diff --git a/examples/investment_analysis.py b/examples/investment_analysis.py index db7ab8b..7a930cb 100644 --- a/examples/investment_analysis.py +++ b/examples/investment_analysis.py @@ -75,7 +75,7 @@ def main(): print("-" * 80) print(f" Deal Count: {result['deal_count']}") print(f" Avg Price: ₪{result['avg_price']:,.0f}") - if result['avg_price_per_sqm']: + if result["avg_price_per_sqm"]: print(f" Avg Price/m²: ₪{result['avg_price_per_sqm']:,.0f}") print(f" Activity: {result['activity_score']:.0f}/100 ({result['activity_level']})") print(f" Liquidity: {result['liquidity_score']:.0f}/100") diff --git a/examples/valuation.py b/examples/valuation.py index 95ac733..87ee09f 100644 --- a/examples/valuation.py +++ b/examples/valuation.py @@ -30,7 +30,9 @@ def main(): try: # Get comparable deals with filters deals = client.find_recent_deals_for_address( - address, years_back=2, radius=200 # Wider radius for more comparables + address, + years_back=2, + radius=200, # Wider radius for more comparables ) if not deals: diff --git a/tests/api_health/test_govmap_api_health.py b/tests/api_health/test_govmap_api_health.py index 1651ca6..2e31fe1 100644 --- a/tests/api_health/test_govmap_api_health.py +++ b/tests/api_health/test_govmap_api_health.py @@ -170,9 +170,9 @@ class TestAPIDataQuality: # Check deal amounts are reasonable (10K to 100M NIS) for deal in deals: if deal.deal_amount > 0: - assert ( - 10000 <= deal.deal_amount <= 100000000 - ), f"Deal amount {deal.deal_amount} outside reasonable range" + assert 10000 <= deal.deal_amount <= 100000000, ( + f"Deal amount {deal.deal_amount} outside reasonable range" + ) @pytest.mark.api_health def test_dates_are_recent(self, client): diff --git a/tests/test_govmap_client.py b/tests/test_govmap_client.py index 579ba27..a5448d5 100644 --- a/tests/test_govmap_client.py +++ b/tests/test_govmap_client.py @@ -120,10 +120,11 @@ class TestGovmapClient: ) # We'll test the coordinate parsing logic by calling the method that uses it - with patch.object(client, "autocomplete_address", return_value=mock_autocomplete_result), \ - patch.object(client, "get_deals_by_radius", return_value=[]), \ - patch.object(client, "get_street_deals", return_value=[]), \ - patch.object(client, "get_neighborhood_deals", return_value=[]): + with patch.object( + client, "autocomplete_address", return_value=mock_autocomplete_result + ), patch.object(client, "get_deals_by_radius", return_value=[]), patch.object( + client, "get_street_deals", return_value=[] + ), patch.object(client, "get_neighborhood_deals", return_value=[]): result = client.find_recent_deals_for_address("test", years_back=1) assert result == [] @@ -333,8 +334,9 @@ class TestGovmapClient: ], ) - with patch.object(client, "autocomplete_address", return_value=mock_autocomplete_result), \ - pytest.raises(ValueError, match="No coordinates found"): + with patch.object( + client, "autocomplete_address", return_value=mock_autocomplete_result + ), pytest.raises(ValueError, match="No coordinates found"): client.find_recent_deals_for_address("test", years_back=1)