import os import logging import requests from typing import Optional log = logging.getLogger(__name__) API_BASE = os.getenv("EVER_JOBS_API_URL", "http://localhost:3001") SEARCH_ENDPOINT = f"{API_BASE}/api/jobs/search" DEFAULT_TIMEOUT = 120 DEFAULT_REQUEST_TIMEOUT = 30 class EverJobsClient: def __init__(self, base_url: str = API_BASE, timeout: int = DEFAULT_TIMEOUT): self.base_url = base_url self.timeout = timeout self.search_endpoint = f"{base_url}/api/jobs/search" def search( self, site_types: list[str], search_term: str, location: str, results_wanted: int = 25, hours_old: int = 168, description_format: str = "plain", request_timeout: int = DEFAULT_REQUEST_TIMEOUT, ) -> list[dict]: payload = { "siteType": [s.lower() for s in site_types], "searchTerm": search_term, "location": location, "resultsWanted": results_wanted, "hoursOld": hours_old, "descriptionFormat": description_format, "requestTimeout": request_timeout, } try: log.info( f"EverJobsClient.search: {site_types} | {search_term!r} @ {location!r} " f"| wanted={results_wanted}" ) resp = requests.post( self.search_endpoint, json=payload, timeout=self.timeout, ) resp.raise_for_status() data = resp.json() jobs = data.get("jobs", []) log.info(f"EverJobsClient: received {len(jobs)} jobs (count={data.get('count')})") return jobs except requests.exceptions.ConnectionError: log.error( "EverJobsClient: connection refused on localhost:3001. " "Run ensure_running() from src.ever_jobs_bridge.server before scraping." ) return [] except requests.exceptions.Timeout: log.error( f"EverJobsClient: request timed out after {self.timeout}s. " "Consider reducing the number of platforms per call." ) return [] except Exception as e: log.error(f"EverJobsClient.search error: {e}") return []