Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -8,7 +8,6 @@ logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(
|
|
| 8 |
logger = logging.getLogger(__name__)
|
| 9 |
mcp = FastMCP("Jobicy Remote Jobs Agent")
|
| 10 |
|
| 11 |
-
# Remaining filter options
|
| 12 |
COMPANY_INDUSTRIES = [
|
| 13 |
("", ""),
|
| 14 |
("Business Development", "business"),
|
|
@@ -41,18 +40,6 @@ COUNTRY_CHOICES = [
|
|
| 41 |
|
| 42 |
@mcp.tool(name="search_jobs")
|
| 43 |
def search_jobs_tool(industry: str = "", country: str = "", keyword: str = "", limit: int = 20) -> dict:
|
| 44 |
-
"""
|
| 45 |
-
Search remote jobs via Jobicy API, supports filters.
|
| 46 |
-
|
| 47 |
-
Args:
|
| 48 |
-
industry (str): Company industry filter.
|
| 49 |
-
country (str): Region filter (e.g., usa, canada, ...).
|
| 50 |
-
keyword (str): Free-form keyword tag.
|
| 51 |
-
limit (int): Number of results (1–50).
|
| 52 |
-
|
| 53 |
-
Returns:
|
| 54 |
-
dict: {"jobs": [...]} or {"error": "..." }
|
| 55 |
-
"""
|
| 56 |
base = "https://jobicy.com/api/v2/remote-jobs"
|
| 57 |
params = {"count": max(1, min(limit, 50))}
|
| 58 |
if industry:
|
|
@@ -63,8 +50,17 @@ def search_jobs_tool(industry: str = "", country: str = "", keyword: str = "", l
|
|
| 63 |
params["tag"] = keyword.strip()
|
| 64 |
|
| 65 |
logger.info(f"Requesting Jobicy API with params: {params}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
try:
|
| 67 |
-
resp =
|
| 68 |
resp.raise_for_status()
|
| 69 |
jobs_raw = resp.json().get("jobs", [])
|
| 70 |
except Exception as e:
|
|
@@ -88,7 +84,30 @@ def search_jobs_tool(industry: str = "", country: str = "", keyword: str = "", l
|
|
| 88 |
sorted_jobs = sorted(jobs_raw, key=lambda x: x.get("pubDate", ""), reverse=True)[:params["count"]]
|
| 89 |
return {"jobs": [fmt(j) for j in sorted_jobs]}
|
| 90 |
|
| 91 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
res = search_jobs_tool(industry=industry, country=country, keyword=keyword, limit=limit)
|
| 93 |
if "error" in res:
|
| 94 |
return f"❌ {res['error']}"
|
|
@@ -97,7 +116,6 @@ def search_jobs_ui(industry, country, keyword, limit):
|
|
| 97 |
|
| 98 |
md = "# Remote Jobs Results\n\n"
|
| 99 |
for i, j in enumerate(res["jobs"], 1):
|
| 100 |
-
# Create Google Search URL for job title + company
|
| 101 |
search_query = f"{j['title']} {j['company']}"
|
| 102 |
search_url = f"https://www.google.com/search?q={requests.utils.quote(search_query)}"
|
| 103 |
|
|
|
|
| 8 |
logger = logging.getLogger(__name__)
|
| 9 |
mcp = FastMCP("Jobicy Remote Jobs Agent")
|
| 10 |
|
|
|
|
| 11 |
COMPANY_INDUSTRIES = [
|
| 12 |
("", ""),
|
| 13 |
("Business Development", "business"),
|
|
|
|
| 40 |
|
| 41 |
@mcp.tool(name="search_jobs")
|
| 42 |
def search_jobs_tool(industry: str = "", country: str = "", keyword: str = "", limit: int = 20) -> dict:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
base = "https://jobicy.com/api/v2/remote-jobs"
|
| 44 |
params = {"count": max(1, min(limit, 50))}
|
| 45 |
if industry:
|
|
|
|
| 50 |
params["tag"] = keyword.strip()
|
| 51 |
|
| 52 |
logger.info(f"Requesting Jobicy API with params: {params}")
|
| 53 |
+
|
| 54 |
+
session = requests.Session()
|
| 55 |
+
session.headers.update({
|
| 56 |
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0 Safari/537.36",
|
| 57 |
+
"Accept": "application/json, text/javascript, */*; q=0.01",
|
| 58 |
+
"Referer": "https://jobicy.com/remote-jobs",
|
| 59 |
+
"Origin": "https://jobicy.com",
|
| 60 |
+
})
|
| 61 |
+
|
| 62 |
try:
|
| 63 |
+
resp = session.get(base, params=params, timeout=10)
|
| 64 |
resp.raise_for_status()
|
| 65 |
jobs_raw = resp.json().get("jobs", [])
|
| 66 |
except Exception as e:
|
|
|
|
| 84 |
sorted_jobs = sorted(jobs_raw, key=lambda x: x.get("pubDate", ""), reverse=True)[:params["count"]]
|
| 85 |
return {"jobs": [fmt(j) for j in sorted_jobs]}
|
| 86 |
|
| 87 |
+
def search_jobs_tool(industry: str = "", country: str = "", keyword: str = "", limit: int = 20) -> dict:
|
| 88 |
+
"""
|
| 89 |
+
Search remote jobs from the Jobicy API with optional filters.
|
| 90 |
+
|
| 91 |
+
Parameters:
|
| 92 |
+
industry (str): Company industry to filter jobs by (e.g., 'business', 'design-multimedia').
|
| 93 |
+
Leave empty to include all industries.
|
| 94 |
+
country (str): Region or country to filter jobs by (e.g., 'usa', 'canada').
|
| 95 |
+
Leave empty or 'anywhere' to include all locations.
|
| 96 |
+
keyword (str): Keyword or tag to search for in job listings (e.g., 'python', 'data').
|
| 97 |
+
Leave empty for no keyword filtering.
|
| 98 |
+
limit (int): Number of job results to return, between 1 and 50. Defaults to 20.
|
| 99 |
+
|
| 100 |
+
Returns:
|
| 101 |
+
dict: A dictionary with a "jobs" key containing a list of job dictionaries with:
|
| 102 |
+
- title: Job title
|
| 103 |
+
- company: Company name
|
| 104 |
+
- location: Job location
|
| 105 |
+
- url: Application or job posting URL
|
| 106 |
+
- pubDate: Date posted (YYYY-MM-DD)
|
| 107 |
+
- salary: Salary range or 'Not specified'
|
| 108 |
+
|
| 109 |
+
Or an "error" key with an error message if the fetch fails.
|
| 110 |
+
"""
|
| 111 |
res = search_jobs_tool(industry=industry, country=country, keyword=keyword, limit=limit)
|
| 112 |
if "error" in res:
|
| 113 |
return f"❌ {res['error']}"
|
|
|
|
| 116 |
|
| 117 |
md = "# Remote Jobs Results\n\n"
|
| 118 |
for i, j in enumerate(res["jobs"], 1):
|
|
|
|
| 119 |
search_query = f"{j['title']} {j['company']}"
|
| 120 |
search_url = f"https://www.google.com/search?q={requests.utils.quote(search_query)}"
|
| 121 |
|