Ran ruff format etc.
This commit is contained in:
@@ -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/
|
- 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
|
### Running the Server
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
+47
-12
@@ -34,7 +34,28 @@ pip install -r requirements.txt
|
|||||||
pip install -r requirements-dev.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
|
```bash
|
||||||
# Run tests
|
# Run tests
|
||||||
@@ -43,6 +64,9 @@ pytest tests/ -m "not api_health" -q
|
|||||||
# Check code quality
|
# Check code quality
|
||||||
ruff check .
|
ruff check .
|
||||||
ruff format --check .
|
ruff format --check .
|
||||||
|
|
||||||
|
# Or use the quick check script
|
||||||
|
./check-quality.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
## Development Workflow
|
## Development Workflow
|
||||||
@@ -59,21 +83,29 @@ git checkout -b fix/issue-description
|
|||||||
|
|
||||||
Follow the code style guidelines below.
|
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
|
```bash
|
||||||
# Run fast tests
|
./check-quality.sh
|
||||||
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
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 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
|
```bash
|
||||||
# Format code
|
# Format code
|
||||||
ruff format .
|
ruff format .
|
||||||
@@ -81,11 +113,14 @@ ruff format .
|
|||||||
# Lint code
|
# Lint code
|
||||||
ruff check . --fix
|
ruff check . --fix
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
pytest tests/ -m "not api_health" -q
|
||||||
|
|
||||||
# Check remaining issues
|
# Check remaining issues
|
||||||
ruff check .
|
ruff check .
|
||||||
```
|
```
|
||||||
|
|
||||||
### 5. Commit Changes
|
### 4. Commit Changes
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add .
|
git add .
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ def main():
|
|||||||
print("-" * 80)
|
print("-" * 80)
|
||||||
print(f" Deal Count: {result['deal_count']}")
|
print(f" Deal Count: {result['deal_count']}")
|
||||||
print(f" Avg Price: ₪{result['avg_price']:,.0f}")
|
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" Avg Price/m²: ₪{result['avg_price_per_sqm']:,.0f}")
|
||||||
print(f" Activity: {result['activity_score']:.0f}/100 ({result['activity_level']})")
|
print(f" Activity: {result['activity_score']:.0f}/100 ({result['activity_level']})")
|
||||||
print(f" Liquidity: {result['liquidity_score']:.0f}/100")
|
print(f" Liquidity: {result['liquidity_score']:.0f}/100")
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ def main():
|
|||||||
try:
|
try:
|
||||||
# Get comparable deals with filters
|
# Get comparable deals with filters
|
||||||
deals = client.find_recent_deals_for_address(
|
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:
|
if not deals:
|
||||||
|
|||||||
@@ -170,9 +170,9 @@ class TestAPIDataQuality:
|
|||||||
# Check deal amounts are reasonable (10K to 100M NIS)
|
# Check deal amounts are reasonable (10K to 100M NIS)
|
||||||
for deal in deals:
|
for deal in deals:
|
||||||
if deal.deal_amount > 0:
|
if deal.deal_amount > 0:
|
||||||
assert (
|
assert 10000 <= deal.deal_amount <= 100000000, (
|
||||||
10000 <= deal.deal_amount <= 100000000
|
f"Deal amount {deal.deal_amount} outside reasonable range"
|
||||||
), f"Deal amount {deal.deal_amount} outside reasonable range"
|
)
|
||||||
|
|
||||||
@pytest.mark.api_health
|
@pytest.mark.api_health
|
||||||
def test_dates_are_recent(self, client):
|
def test_dates_are_recent(self, client):
|
||||||
|
|||||||
@@ -120,10 +120,11 @@ class TestGovmapClient:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# We'll test the coordinate parsing logic by calling the method that uses it
|
# 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), \
|
with patch.object(
|
||||||
patch.object(client, "get_deals_by_radius", return_value=[]), \
|
client, "autocomplete_address", return_value=mock_autocomplete_result
|
||||||
patch.object(client, "get_street_deals", return_value=[]), \
|
), patch.object(client, "get_deals_by_radius", return_value=[]), patch.object(
|
||||||
patch.object(client, "get_neighborhood_deals", return_value=[]):
|
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)
|
result = client.find_recent_deals_for_address("test", years_back=1)
|
||||||
assert result == []
|
assert result == []
|
||||||
|
|
||||||
@@ -333,8 +334,9 @@ class TestGovmapClient:
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
with patch.object(client, "autocomplete_address", return_value=mock_autocomplete_result), \
|
with patch.object(
|
||||||
pytest.raises(ValueError, match="No coordinates found"):
|
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)
|
client.find_recent_deals_for_address("test", years_back=1)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user