OppaAI's picture
Update app.py
e80edff verified
raw
history blame
4.94 kB
import gradio as gr
from fastmcp import FastMCP
import logging
import requests
from datetime import datetime
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)
mcp = FastMCP("Jobicy Remote Jobs Agent")
# Remaining filter options
COMPANY_INDUSTRIES = [
("", ""),
("Business Development", "business"),
("Content & Editorial", "copywriting"),
("Creative & Design", "design-multimedia"),
("Customer Success", "supporting"),
("Data Science & Analytics", "data-science"),
("DevOps & Infrastructure", "admin"),
("Finance & Accounting", "accounting-finance"),
("HR & Recruiting", "hr"),
("Legal & Compliance", "legal"),
("Marketing & Sales", "marketing"),
("Product & Operations", "management"),
("Programming", "dev"),
("Sales", "seller"),
("SEO", "seo"),
("Social Media Marketing", "smm"),
("Software Engineering", "engineering"),
("Technical Support", "technical-support"),
("Web & App Design", "web-app-design"),
]
COUNTRY_CHOICES = [
"", "APAC", "EMEA", "LATAM", "Argentina", "Australia", "Austria", "Belgium", "Brazil", "Bulgaria",
"Canada", "China", "Costa Rica", "Croatia", "Cyprus", "Czechia", "Denmark", "Estonia", "Europe",
"Finland", "France", "Germany", "Greece", "Hungary", "Ireland", "Israel", "Italy", "Japan",
"Latvia", "Lithuania", "Mexico", "Netherlands", "New Zealand", "Norway", "Philippines", "Poland",
"Portugal", "Romania", "Singapore", "Slovakia", "Slovenia", "South Korea", "Spain", "Sweden",
"Switzerland", "Thailand", "Türkiye", "UAE", "UK", "USA", "Vietnam"
]
@mcp.tool(name="search_jobs")
def search_jobs_tool(industry: str = "", country: str = "", keyword: str = "", limit: int = 20) -> dict:
"""
Search remote jobs via Jobicy API, supports filters.
Args:
industry (str): Company industry filter.
country (str): Region filter (e.g., usa, canada, ...).
keyword (str): Free-form keyword tag.
limit (int): Number of results (1–50).
Returns:
dict: {"jobs": [...]} or {"error": "..." }
"""
base = "https://jobicy.com/api/v2/remote-jobs"
params = {"count": max(1, min(limit, 50))}
if industry:
params["industry"] = industry.lower().replace(" & ", "-").replace(" ", "-")
if country and country.lower() != "anywhere":
params["geo"] = country.lower()
if keyword:
params["tag"] = keyword.strip()
logger.info(f"Requesting Jobicy API with params: {params}")
try:
resp = requests.get(base, params=params, headers={"User-Agent": "Mozilla/5.0"}, timeout=10)
resp.raise_for_status()
jobs_raw = resp.json().get("jobs", [])
except Exception as e:
return {"error": f"Fetch error: {e}"}
def fmt(j):
posted = j.get("pubDate", "")[:10]
sal_min = j.get("annualSalaryMin")
sal_max = j.get("annualSalaryMax")
cur = j.get("salaryCurrency", "")
salary = f"{sal_min}{sal_max} {cur}".strip() if sal_min or sal_max else "Not specified"
return {
"title": j.get("jobTitle", "No Title"),
"company": j.get("companyName", ""),
"location": j.get("jobGeo", ""),
"url": j.get("url", "#"),
"pubDate": posted,
"salary": salary
}
sorted_jobs = sorted(jobs_raw, key=lambda x: x.get("pubDate", ""), reverse=True)[:params["count"]]
return {"jobs": [fmt(j) for j in sorted_jobs]}
def search_jobs_ui(industry, country, keyword, limit):
res = search_jobs_tool(industry=industry, country=country, keyword=keyword, limit=limit)
if "error" in res:
return f"❌ {res['error']}"
if not res["jobs"]:
return "No jobs found with these filters."
md = "# Remote Jobs Results\n\n"
for i, j in enumerate(res["jobs"], 1):
md += (
f"### {i}. {j['title']}\n\n"
f"**Company:** {j['company']}\n\n"
f"**Location:** {j['location']}\n\n"
f"**Salary:** {j['salary']}\n\n"
f"**Posted On:** {j['pubDate']}\n\n"
f"[Apply Here]({j['url']})\n\n---\n\n"
)
return md
app = gr.Interface(
fn=search_jobs_ui,
inputs=[
gr.Dropdown(label="Company Industry (optional) (Empty = All)", choices=COMPANY_INDUSTRIES, value=""),
gr.Dropdown(label="Country / Region (optional) (Empty = Anywhere)", choices=COUNTRY_CHOICES, value=""),
gr.Textbox(label="Keyword / Tag (optional)", placeholder="e.g., python, data, web"),
gr.Slider(minimum=1, maximum=50, value=20, step=1, label="Number of Results"),
],
outputs=gr.Markdown(),
title="Jobicy Remote Job Search",
description="Search remote jobs by industry, region, and keyword. Results sorted by most recent.",
theme="huggingface"
)
if __name__ == "__main__":
app.launch(mcp_server=True)