from fastapi import FastAPI, HTTPException, APIRouter, Request, Header, Depends from fastapi import BackgroundTasks from fastapi.responses import JSONResponse import json from fastapi.templating import Jinja2Templates from sqlalchemy.ext.asyncio import async_sessionmaker from typing import Dict from pydantic import BaseModel from sqlalchemy.orm import Session import json from model.database import get_async_session, Client from utils.clients import upsert_client, del_jobs, add_jobs, get_applied_jobs, get_filtered_jobs, client_list, get_avtopilot, get_delite, get_update from typing import Union import asyncio router = APIRouter() templates = Jinja2Templates(directory="templates") API_KEY = "4545454" def get_filtered_values(category, data): values = data.get(category, {}) if isinstance(values, dict): # Фильтруем словарь, оставляем только значения, отличные от None return [key for key, value in values.items() if value is not None] elif isinstance(values, str) and values: # Если это строка, добавляем её как есть (если она не пустая) return [values] return [] # Пример данных clients = { 1: {"username": "John Doe", "email": "john@example.com", "phone": "+123456781"}, 44: {"username": "Jane Smith", "email": "jane@example.com", "phone": "+987654321"} } @router.get("/get_client/{client_id}", include_in_schema=False) async def get_client_modal(client_id: int, db: Session = Depends(get_async_session)): # client = clients.get(client_id) # Используй clients вместо clients_db # print(f"==============================={type(client)}") client = await client_list(client_id, db) if not client: raise HTTPException(status_code=404, detail="Client not found") return JSONResponse(content=client) class JsonData(BaseModel): json_data: Union[dict, str] class jobs_delete(BaseModel): user_id: int job_id:int class avtopilots(BaseModel): user_id: int avtopilot:bool class update(BaseModel): user_id: int async def process_client_data( db: Session, data: JsonData, user_id: str, first_name: str, last_name: str, email_addr: str, phone_num: str ): """Функция для обработки данных в фоне""" print(f"Получены данные для {first_name} {last_name} с email {email_addr}") async_session_maker = async_sessionmaker(bind=db.bind, expire_on_commit=False) async with async_session_maker() as db1, async_session_maker() as db2: print("Запускаем задачи для обновления и удаления") client_task = upsert_client(db1, user_id, first_name, last_name, email_addr, phone_num, str(data.json_data)) del_task = del_jobs(db2, user_id) client, _ = await asyncio.gather(client_task, del_task) job_level_values = get_filtered_values('job_level', data.json_data) job_type_values = get_filtered_values('job_type', data.json_data) location_type_values = get_filtered_values('location_type', data.json_data) print("Job Level:", ", ".join(job_level_values)) print("Job Type:", ", ".join(job_type_values)) print("Location Type:", ", ".join(location_type_values)) jobs = await get_filtered_jobs( db, user_job_titles=["Electronics Engineer", "Hardware Engineer"], minimum_annual_salary=None, salary_currency=None, user_location_type=None, user_locations=["Burnaby, Canada", "Vancouver, Canada", "Toronto, Canada"], user_levels=["Mid", "Senior", "Manager"], user_job_types=["Full-time", "Permanent"] ) for job in jobs: print(job.job_title, job.location, job.job_level, job.job_type) ads = await add_jobs(db, user_id) get_jobs = await get_applied_jobs(db, user_id) # [ ]: NOTE Рабоиа в фоне BackgroundTasks process_client_data() @router.post("/client/", summary="Обновления json_data и переобновление вакансий", description="Этот эндпоинт обновляет json_data, удаляет все вакансии со статусом Scheduled и создаёт по полученным данным новые вакансии") async def client( data: JsonData, x_api_key: str = Header(...), db: Session = Depends(get_async_session), background_tasks: BackgroundTasks = BackgroundTasks() ): if x_api_key != "4545454": raise HTTPException(status_code=403, detail="Invalid API Key") # Если json_data строка, декодируем её в словарь if isinstance(data.json_data, str): try: data.json_data = json.loads(data.json_data) except json.JSONDecodeError: raise HTTPException(status_code=400, detail="Invalid JSON format") # Проверяем что данные в нужном формате if not isinstance(data.json_data, dict): raise HTTPException(status_code=400, detail="Invalid data format") try: # Извлекаем основные данные first_name = data.json_data['first_name'] last_name = data.json_data['last_name'] email_addr = data.json_data['email_addr'] user_id = data.json_data['user_id'] phone_num = data.json_data['phone_num'] # Добавляем фоновые задачи background_tasks.add_task( process_client_data, db=db, data=data, user_id=user_id, first_name=first_name, last_name=last_name, email_addr=email_addr, phone_num=phone_num ) except KeyError as e: raise HTTPException(status_code=400, detail=f"Missing required field: {e}") return {"status": "ok", "message": "Request received and is being processed"} # @router.post("/client/") # async def client(data: JsonData, x_api_key: str = Header(...), db: Session = Depends(get_async_session)): # if x_api_key != "4545454": # raise HTTPException(status_code=403, detail="Invalid API Key") # # Если json_data строка, декодируем её в словарь # if isinstance(data.json_data, str): # try: # data.json_data = json.loads(data.json_data) # Декодируем строку в словарь # except json.JSONDecodeError: # raise HTTPException(status_code=400, detail="Invalid JSON format") # # Если json_data строка — декодируем # # Теперь data.json_data гарантированно является словарем # if isinstance(data.json_data, dict): # try: # first_name = data.json_data['first_name'] # last_name = data.json_data['last_name'] # email_addr = data.json_data['email_addr'] # user_id = data.json_data['user_id'] # phone_num = data.json_data['phone_num'] # print(f"Получены данные для {first_name} {last_name} с email {email_addr}") # async_session_maker = async_sessionmaker(bind=db.bind, expire_on_commit=False) # async with async_session_maker() as db1, async_session_maker() as db2: # print("Запускаем задачи для обновления и удаления") # client_task = upsert_client(db1, user_id, first_name, last_name, email_addr, phone_num, str(data.json_data)) # del_task = del_jobs(db2, user_id) # client, _ = await asyncio.gather(client_task, del_task) # job_level_values = get_filtered_values('job_level', data.json_data) # job_type_values = get_filtered_values('job_type', data.json_data) # location_type_values = get_filtered_values('location_type', data.json_data) # #Результат # print("Job Level:", ", ".join(job_level_values)) # print("Job Type:", ", ".join(job_type_values)) # print("Location Type:", ", ".join(location_type_values)) # # Пример использования функции # jobs = await get_filtered_jobs( # db, # user_job_titles=["Electronics Engineer", "Hardware Engineer"], # minimum_annual_salary=None, # salary_currency=None, # user_location_type=None, # user_locations=["Burnaby, Canada", "Vancouver, Canada", "Toronto, Canada"], # user_levels=["Mid", "Senior", "Manager"], # user_job_types=["Full-time", "Permanent"] # ) # # Выводим вакансии # for job in jobs: # print(job.job_title, job.location, job.job_level, job.job_type) # ads = await add_jobs(db, user_id) # get_jobs = await get_applied_jobs(db, user_id) # # print(f"Полученные заявки: {get_jobs}") # except KeyError as e: # print(f"Ошибка при извлечении данных: {e}") # raise HTTPException(status_code=400, detail="Missing required field in json_data") # else: # # print(f"Неверный формат данных: {type(data.json_data)}") # raise HTTPException(status_code=400, detail="Invalid data format") # return {"status": "ok", "message": "JSON получен"} @router.post("/client_update", summary="Обновления клиента", description="Этот эндпоинт получает ID пользователя, переходит по ссылки что бы получить json_data") async def client_update(data: update, x_api_key: str = Header(...), db: Session = Depends(get_async_session)): if x_api_key != "4545454": raise HTTPException(status_code=403, detail="Invalid API Key") try: user_id = data.user_id # Обратите внимание на точку вместо квадратных скобок await get_update(db, data) except Exception as e: print(f"Ошибка при обработке данных: {e}") raise HTTPException(status_code=400, detail="Error processing data") return {"status": "ok", "message": "Data received", "user_id": user_id, } @router.post("/client_jobs/", summary="Получить список работ по клиенту", description="Этот эндпоинт получает ID пользователя, в ответ отдаёт список вакансий") async def client_jobs(data: update, x_api_key: str = Header(...), db: Session = Depends(get_async_session)): if x_api_key != "4545454": raise HTTPException(status_code=403, detail="Invalid API Key") try: user_id = data.user_id # Обратите внимание на точку вместо квадратных скобок get_jobs = await get_applied_jobs(db, user_id) print(f"Полученные данные: user_id={user_id}") except Exception as e: print(f"Ошибка при обработке данных: {e}") raise HTTPException(status_code=400, detail="Error processing data") return {"status": "ok", "message": "Data received", "get_jobs": get_jobs} # return {"message": "JSON получен", "data": get_jobs} @router.post("/avtopilot", summary="Автопилот вкл, выкл", description="Этот эндпоинт получает ID пользователя, включает или отключает автопилот. При false все вакансии со статусом Scheduled становятся Paused при true наоборот!") async def avtopilot(data: avtopilots, x_api_key: str = Header(...), db: Session = Depends(get_async_session)): if x_api_key != "4545454": raise HTTPException(status_code=403, detail="Invalid API Key") try: user_id = data.user_id # Обратите внимание на точку вместо квадратных скобок avtopilotss = data.avtopilot # Так как data - это объект Pydantic модели await get_avtopilot(db, data) except Exception as e: print(f"Ошибка при обработке данных: {e}") raise HTTPException(status_code=400, detail="Error processing data") return {"status": "ok", "message": "Data received", "user_id": user_id, "avtopilotss": avtopilotss} @router.post("/jobs_delete", summary="Удаление вакансии", description="Этот эндпоинт получает ID пользователя и ID вакансии, Удаляет у пользователя вакансию") async def jobs_delete(data: jobs_delete, x_api_key: str = Header(...), db: Session = Depends(get_async_session)): if x_api_key != "4545454": raise HTTPException(status_code=403, detail="Invalid API Key") try: user_id = data.user_id # Обратите внимание на точку вместо квадратных скобок job_id = data.job_id # Так как data - это объект Pydantic модели await get_delite(db, data) except Exception as e: print(f"Ошибка при обработке данных: {e}") raise HTTPException(status_code=400, detail="Error processing data") return {"status": "ok", "message": "Data received", "user_id": user_id, "job_id": job_id}