Major changes: - Add TLD price scraper with Porkbun API (886+ TLDs, no API key needed) - Fix .ch domain checker using rdap.nic.ch custom RDAP - Integrate database for TLD price history tracking - Add admin endpoints for manual scrape and stats - Extend scheduler with daily TLD price scrape job (03:00 UTC) - Update API to use DB data with static fallback - Update README with complete documentation New files: - backend/app/services/tld_scraper/ (scraper package) - TLD_TRACKING_PLAN.md (implementation plan) API changes: - POST /admin/scrape-tld-prices - trigger manual scrape - GET /admin/tld-prices/stats - database statistics - GET /tld-prices/overview now uses DB data
74 lines
2.3 KiB
Python
74 lines
2.3 KiB
Python
"""Public domain check API (no auth required)."""
|
|
from datetime import datetime
|
|
|
|
from fastapi import APIRouter, HTTPException, status
|
|
|
|
from app.schemas.domain import DomainCheckRequest, DomainCheckResponse
|
|
from app.services.domain_checker import domain_checker
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.post("", response_model=DomainCheckResponse)
|
|
async def check_domain_availability(request: DomainCheckRequest):
|
|
"""
|
|
Check if a domain is available.
|
|
|
|
This endpoint is public and does not require authentication.
|
|
For quick checks, set `quick=true` to use DNS-only lookup (faster but less detailed).
|
|
"""
|
|
# Validate domain format
|
|
is_valid, error = domain_checker.validate_domain(request.domain)
|
|
if not is_valid:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail=error,
|
|
)
|
|
|
|
# Check domain
|
|
result = await domain_checker.check_domain(request.domain, quick=request.quick)
|
|
|
|
return DomainCheckResponse(
|
|
domain=result.domain,
|
|
status=result.status.value,
|
|
is_available=result.is_available,
|
|
registrar=result.registrar,
|
|
expiration_date=result.expiration_date,
|
|
creation_date=result.creation_date,
|
|
name_servers=result.name_servers,
|
|
error_message=result.error_message,
|
|
checked_at=datetime.utcnow(),
|
|
)
|
|
|
|
|
|
@router.get("/{domain}", response_model=DomainCheckResponse)
|
|
async def check_domain_get(domain: str, quick: bool = False):
|
|
"""
|
|
Check domain availability via GET request.
|
|
|
|
Useful for quick lookups. Domain should be URL-encoded if it contains special characters.
|
|
"""
|
|
# Validate domain format
|
|
is_valid, error = domain_checker.validate_domain(domain)
|
|
if not is_valid:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail=error,
|
|
)
|
|
|
|
# Check domain
|
|
result = await domain_checker.check_domain(domain, quick=quick)
|
|
|
|
return DomainCheckResponse(
|
|
domain=result.domain,
|
|
status=result.status.value,
|
|
is_available=result.is_available,
|
|
registrar=result.registrar,
|
|
expiration_date=result.expiration_date,
|
|
creation_date=result.creation_date,
|
|
name_servers=result.name_servers,
|
|
error_message=result.error_message,
|
|
checked_at=datetime.utcnow(),
|
|
)
|
|
|