diff --git a/routers/client.py b/routers/client.py index d81600d..3735c7f 100644 --- a/routers/client.py +++ b/routers/client.py @@ -1,317 +1,322 @@ -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} +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 + +from types import SimpleNamespace + + + + + +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 [] + +# Пример данных + +@router.get("/get_client/{client_id}", include_in_schema=False) +async def get_client_modal(client_id: int, db: Session = Depends(get_async_session)): + data = SimpleNamespace(user_id=client_id) + print(data) + await get_update(db, data) + + client = await client_list(client_id, db) + + # print(client) + + + + 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=["3D Modeler,3D Printing Technician,3D Visualizer"], + 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=["Part-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}