Spaces:
Sleeping
Sleeping
| # Job Tracker Agent - First Version with Gradio + JSON Memory + CSV Export (No OpenAI Key) | |
| # - Uses Hugging Face Inference API (Mistral-7B) | |
| # - Extracts job info from text | |
| # - Saves to JSON + allows CSV export | |
| import gradio as gr | |
| import os | |
| import json | |
| import csv | |
| import requests | |
| from datetime import datetime | |
| JOB_LOG_FILE = "job_memory.json" | |
| CSV_EXPORT_FILE = "job_memory.csv" | |
| HF_API_URL = "https://api-inference.huggingface.co/models/HuggingFaceH4/zephyr-7b-beta" | |
| # Optional: use your Hugging Face token for more reliability | |
| HF_API_TOKEN = os.getenv("HUG_API_TOKEN") # or leave None for free/public use | |
| headers = {"Authorization": f"Bearer {HF_API_TOKEN}"} if HF_API_TOKEN else {} | |
| # Initialize memory file | |
| if not os.path.exists(JOB_LOG_FILE): | |
| with open(JOB_LOG_FILE, "w") as f: | |
| json.dump([], f) | |
| # Extract job info using Hugging Face Inference API | |
| def extract_job_details(text): | |
| prompt = f""" | |
| Extract structured JSON with the following fields from the input text: | |
| - company | |
| - role | |
| - location | |
| - source | |
| - status | |
| - link (if present) | |
| - follow_up_date (in YYYY-MM-DD if mentioned, else null) | |
| Input: | |
| {text} | |
| Output: | |
| """ | |
| payload = { | |
| "inputs": prompt, | |
| "parameters": {"max_new_tokens": 500}, | |
| "options": {"wait_for_model": True} | |
| } | |
| try: | |
| response = requests.post(HF_API_URL, headers=headers, json=payload) | |
| response.raise_for_status() | |
| result = response.json() | |
| if isinstance(result, dict) and "error" in result: | |
| return json.dumps(result) | |
| if isinstance(result, list) and "generated_text" in result[0]: | |
| return result[0]["generated_text"].split("Output:")[-1].strip() | |
| return json.dumps({"error": "Unexpected response format"}) | |
| except Exception as e: | |
| return json.dumps({"error": str(e)}) | |
| # Store to JSON file | |
| def store_job_data(parsed_json): | |
| try: | |
| job_data = json.loads(parsed_json) | |
| job_data["logged_at"] = datetime.now().isoformat() | |
| with open(JOB_LOG_FILE, "r+") as f: | |
| existing = json.load(f) | |
| existing.append(job_data) | |
| f.seek(0) | |
| json.dump(existing, f, indent=2) | |
| return "β Job logged successfully." | |
| except Exception as e: | |
| return f"β Error logging job: {e}" | |
| # Read memory safely with missing key handling | |
| def get_job_history(): | |
| with open(JOB_LOG_FILE, "r") as f: | |
| entries = json.load(f) | |
| formatted = "\n\n".join([ | |
| f"{e.get('role', '[Missing Role]')} at {e.get('company', '[Missing Company]')} ({e.get('status', 'Unknown')}) - {e.get('follow_up_date', 'N/A')}" | |
| for e in entries | |
| ]) | |
| return formatted or "No jobs tracked yet." | |
| # Export to CSV | |
| def export_to_csv(): | |
| try: | |
| with open(JOB_LOG_FILE, "r") as f: | |
| entries = json.load(f) | |
| if entries: | |
| keys = set() | |
| for entry in entries: | |
| keys.update(entry.keys()) | |
| keys = sorted(keys) | |
| with open(CSV_EXPORT_FILE, "w", newline='') as f: | |
| writer = csv.DictWriter(f, fieldnames=keys) | |
| writer.writeheader() | |
| writer.writerows(entries) | |
| return f"β Exported to {CSV_EXPORT_FILE}" | |
| return "β No job data to export." | |
| except Exception as e: | |
| return f"β Export failed: {e}" | |
| # Gradio logic | |
| def job_tracker_interface(user_input): | |
| parsed_json = extract_job_details(user_input) | |
| if "error" in parsed_json: | |
| return parsed_json, "β Failed to log job.", get_job_history() | |
| store_status = store_job_data(parsed_json) | |
| memory_state = get_job_history() | |
| return parsed_json, store_status, memory_state | |
| def export_interface(): | |
| return export_to_csv() | |
| # Gradio app | |
| demo = gr.Interface( | |
| fn=job_tracker_interface, | |
| inputs=gr.Textbox(lines=10, label="Paste a job description or job-related email"), | |
| outputs=[ | |
| gr.Textbox(label="π§ Extracted Job Info (JSON)"), | |
| gr.Textbox(label="π₯ Save Status"), | |
| gr.Textbox(label="π Job Tracker Memory (Current Session)") | |
| ], | |
| title="Job Tracker AI (v1) - No OpenAI Key", | |
| description="Paste job descriptions or emails. This AI agent uses Mistral-7B to extract job data, save it in memory, and export to CSV." | |
| ) | |
| export_demo = gr.Interface( | |
| fn=export_interface, | |
| inputs=[], | |
| outputs=gr.Textbox(label="π€ Export Result"), | |
| title="Export to CSV", | |
| description="Click the button below to export your job data to a CSV file." | |
| ) | |
| demo.launch() | |
| # Optionally launch CSV export in a separate tab | |
| # export_demo.launch() | |