Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/sync with backend #98

Merged
merged 46 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
4c12044
feat: Version each of bot & df_designer dirs
Ramimashkouk Jun 7, 2024
5fc58c5
Merge branch 'dev' into feat/version-user-proj2
Ramimashkouk Aug 8, 2024
683f5f6
style: Black up
Ramimashkouk Aug 8, 2024
7ffb675
fix: Delete is_alive & slot interface
Ramimashkouk Oct 4, 2024
2c4a105
fix: Run python3 if python wasn't found
Ramimashkouk Oct 8, 2024
ca9c92f
refactor: Reorganize json_converter into classes
Ramimashkouk Oct 11, 2024
0b888b5
refactor: Add store_custom_services
Ramimashkouk Oct 11, 2024
dd4f67c
Merge branch 'fix/slots' into test/fix-tests
Ramimashkouk Oct 28, 2024
8aa4bd8
test: Add tests for new json_converter
Ramimashkouk Nov 2, 2024
43e3ff6
fix: Handle building if there's no slot_node in graph
Ramimashkouk Nov 5, 2024
c75b014
refactor: Add dev group in toml file
Ramimashkouk Nov 5, 2024
6727a18
refactor: Use ast instead of the manual old indexing
Ramimashkouk Nov 5, 2024
39f97f6
chore: Update to the new template repo
Ramimashkouk Nov 5, 2024
cc78f17
Merge branch 'feat/version-user-proj2' into refactor/roma-feedback
Ramimashkouk Nov 8, 2024
c437449
chore: Add logging to show weather it's gonna build
Ramimashkouk Nov 8, 2024
7433d33
fix: Save tg_token in .env
Ramimashkouk Nov 8, 2024
af4dab2
feat: Support automatic transitions (previous, ...)
Ramimashkouk Nov 8, 2024
42b8af1
style: Black up
Ramimashkouk Nov 8, 2024
be81934
style: Flake8 up
Ramimashkouk Nov 8, 2024
30f38c6
fix: Check for unique group names
Ramimashkouk Nov 14, 2024
463a746
feat: Integrate slots in responses by FillTemplate
Ramimashkouk Nov 14, 2024
53ea889
feat: Delete websocket and use http_interface
Ramimashkouk Nov 19, 2024
0a84d80
fix: Get last flow not last tag with `/flows`
Ramimashkouk Nov 19, 2024
6a5ef9a
chore: Write logs out in case of stopped process
Ramimashkouk Nov 20, 2024
31d1ef9
test: Fix json-converter tests
Ramimashkouk Nov 20, 2024
ca7b301
fix: Check aliveness of a tg|http process properly
Ramimashkouk Nov 27, 2024
1767b4f
fix: Version with git only when using UI
Ramimashkouk Nov 28, 2024
ba5b4a9
fix: Save built script after end of process
Ramimashkouk Nov 29, 2024
b62d9dd
fix: Return http health checking
Ramimashkouk Nov 29, 2024
11b5101
fix: Set a logger for service_replacer
Ramimashkouk Nov 29, 2024
c434d36
chore: Clean old config refreshing
Ramimashkouk Nov 29, 2024
221a2ff
fix: Save script in periodic-check& separate is_alive
Ramimashkouk Nov 29, 2024
077e758
fix: Return config reload refreshing feature
Ramimashkouk Nov 29, 2024
c1f3696
fix: Terminate a group process with its children
Ramimashkouk Dec 2, 2024
50eb381
websocket removed
artem-mar Dec 2, 2024
afb79a8
fix: Get env vars after reloading if any
Ramimashkouk Dec 2, 2024
b8e9eba
fix responses and conditions
artem-mar Dec 2, 2024
e5aedc3
token sending added
artem-mar Dec 2, 2024
7c1a12c
rename repeat to current
artem-mar Dec 2, 2024
0ac2dd4
Merge branch 'test/fix-tests-up' into fix/sync-with-backend
artem-mar Dec 2, 2024
9491d2b
chore: update dependencies
artem-mar Dec 3, 2024
dc29529
fix: fixed chat functionality
artem-mar Dec 3, 2024
3fd9580
Merge branch 'dev' into fix/sync-with-backend
Ramimashkouk Dec 16, 2024
219345a
update lock file
Ramimashkouk Dec 16, 2024
c130be1
Merge branch 'dev' into fix/sync-with-backend
Ramimashkouk Dec 16, 2024
372d79d
style: Black up
Ramimashkouk Dec 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/e2e_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# push:
# branches:
# - dev
# - master
# pull_request:
# branches:
# - dev
Expand Down
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ ENV PATH="${PATH}:${POETRY_VENV}/bin"
COPY ./backend /temp/backend
COPY --from=frontend-builder /temp/frontend/dist /temp/backend/chatsky_ui/static


# Build the wheel
WORKDIR /temp/backend
RUN poetry build
Expand All @@ -47,6 +46,9 @@ ARG PROJECT_DIR
# Install pip and upgrade
RUN pip install --upgrade pip

# Install Git
RUN apt-get update && apt-get install -y git

# Copy only the necessary files
COPY --from=backend-builder /temp/backend/dist /src/dist
COPY ./${PROJECT_DIR} /src/project_dir
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ init_proj: install_backend_env ## Initiates a new project using chatsky-ui

.PHONY: init_with_cc
init_with_cc: ## Initiates a new project using cookiecutter
cookiecutter https://github.com/Ramimashkouk/df_d_template.git
cookiecutter https://github.com/deeppavlov/chatsky-ui-template.git


.PHONY: build_docs
Expand Down
68 changes: 20 additions & 48 deletions backend/chatsky_ui/api/api_v1/endpoints/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
from typing import Any, Dict, List, Optional, Union

from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, WebSocket, WebSocketException, status
from chatsky.messengers.http_interface import HTTP_INTERFACE_PORT

from chatsky_ui.api import deps
from chatsky_ui.schemas.pagination import Pagination
from chatsky_ui.schemas.preset import Preset
from chatsky_ui.schemas.process_status import Status
from chatsky_ui.services.index import Index
from chatsky_ui.services.process_manager import BuildManager, ProcessManager, RunManager
from chatsky_ui.services.websocket_manager import WebSocketManager
from httpx import AsyncClient

router = APIRouter()

Expand Down Expand Up @@ -45,7 +45,6 @@ async def start_build(
preset: Preset,
background_tasks: BackgroundTasks,
build_manager: BuildManager = Depends(deps.get_build_manager),
index: Index = Depends(deps.get_index),
) -> Dict[str, Union[str, int]]:

"""Starts a `build` process with the given preset.
Expand All @@ -61,7 +60,7 @@ async def start_build(

await asyncio.sleep(preset.wait_time)
build_id = await build_manager.start(preset)
background_tasks.add_task(build_manager.check_status, build_id, index)
background_tasks.add_task(build_manager.check_status, build_id)
build_manager.logger.info("Build process '%s' has started", build_id)
return {"status": "ok", "build_id": build_id}

Expand Down Expand Up @@ -236,47 +235,20 @@ async def get_run_logs(
return await run_manager.fetch_run_logs(run_id, pagination.offset(), pagination.limit)


@router.websocket("/run/connect")
async def connect(
websocket: WebSocket,
websocket_manager: WebSocketManager = Depends(deps.get_websocket_manager),
run_manager: RunManager = Depends(deps.get_run_manager),
) -> None:
"""Establishes a WebSocket connection to communicate with an alive run process identified by its 'run_id'.

The WebSocket URL should adhere to the format: /bot/run/connect?run_id=<run_id>.
"""

run_manager.logger.debug("Connecting to websocket")
run_id = websocket.query_params.get("run_id")

# Validate run_id
if run_id is None:
run_manager.logger.error("No run_id provided")
raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION)
if not run_id.isdigit():
run_manager.logger.error("A non-digit run run_id provided")
raise WebSocketException(code=status.WS_1003_UNSUPPORTED_DATA)
run_id = int(run_id)
if run_id not in run_manager.processes:
run_manager.logger.error("process with run_id '%s' exited or never existed", run_id)
raise WebSocketException(code=status.WS_1014_BAD_GATEWAY)

await websocket_manager.connect(websocket)
run_manager.logger.info("Websocket for run process '%s' has been opened", run_id)

output_task = asyncio.create_task(
websocket_manager.send_process_output_to_websocket(run_id, run_manager, websocket)
)
input_task = asyncio.create_task(
websocket_manager.forward_websocket_messages_to_process(run_id, run_manager, websocket)
)

# Wait for either task to finish
_, websocket_manager.pending_tasks[websocket] = await asyncio.wait(
[output_task, input_task],
return_when=asyncio.FIRST_COMPLETED,
)
websocket_manager.disconnect(websocket)
if await run_manager.get_status(run_id) in [Status.ALIVE, Status.RUNNING]:
await run_manager.stop(run_id)
@router.post("/chat", status_code=201)
async def respond(
user_id: str,
user_message: str,
):
async with AsyncClient() as client:
try:
response = await client.post(
f"http://localhost:{HTTP_INTERFACE_PORT}/chat",
params={"user_id": user_id, "user_message": user_message},
)
return response.json()
except Exception as e:
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail=f"Please check that service's up and running on the port '{HTTP_INTERFACE_PORT}'.",
) from e
26 changes: 15 additions & 11 deletions backend/chatsky_ui/api/api_v1/endpoints/chatsky_services.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,36 @@
import re
from io import StringIO
from typing import Dict, Optional, Union
from typing import Dict, Union

import aiofiles
from fastapi import APIRouter, Depends
from fastapi import APIRouter
from pylint.lint import Run, pylinter
from pylint.reporters.text import TextReporter

from chatsky_ui.api.deps import get_index
from chatsky_ui.clients.chatsky_client import get_chatsky_conditions
from chatsky_ui.core.config import settings
from chatsky_ui.schemas.code_snippet import CodeSnippet
from chatsky_ui.services.index import Index
from chatsky_ui.services.json_converter_new2.logic_component_converter.service_replacer import get_all_classes
from chatsky_ui.utils.ast_utils import get_imports_from_file

router = APIRouter()


@router.get("/search/{service_name}", status_code=200)
async def search_service(service_name: str, index: Index = Depends(get_index)) -> Dict[str, Optional[Union[str, list]]]:
"""Searches for a custom service by name and returns its code.

A service could be a condition, reponse, or pre/postservice.
"""
response = await index.search_service(service_name)
@router.get("/search/condition/{condition_name}", status_code=200)
async def search_condition(condition_name: str) -> Dict[str, Union[str, list]]:
"""Searches for a custom condition by name and returns its code."""
custom_classes = get_all_classes(settings.conditions_path)
response = [custom_class["body"] for custom_class in custom_classes if custom_class["name"] == condition_name]
return {"status": "ok", "data": response}


@router.get("/get_all_custom_conditions", status_code=200)
async def get_all_custom_conditions_names() -> Dict[str, Union[str, list]]:
all_classes = get_all_classes(settings.conditions_path)
custom_classes = [custom_class["body"] for custom_class in all_classes]
return {"status": "ok", "data": custom_classes}


@router.post("/lint_snippet", status_code=200)
async def lint_snippet(snippet: CodeSnippet) -> Dict[str, str]:
"""Lints a snippet with Pylint.
Expand Down
51 changes: 48 additions & 3 deletions backend/chatsky_ui/api/api_v1/endpoints/flows.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,43 @@
from typing import Dict, Union
from typing import Dict, Union, Optional

from fastapi import APIRouter
from fastapi import APIRouter, status, HTTPException
from omegaconf import OmegaConf
from git.exc import GitCommandError

from chatsky_ui.core.config import settings
from chatsky_ui.db.base import read_conf, write_conf
from chatsky_ui.utils.git_cmd import commit_changes, get_repo
from chatsky_ui.core.logger_config import get_logger
from pathlib import Path
from dotenv import set_key


router = APIRouter()


@router.get("/")
async def flows_get() -> Dict[str, Union[str, Dict[str, Union[list, dict]]]]:
async def flows_get(build_id: Optional[int] = None) -> Dict[str, Union[str, Dict[str, Union[list, dict]]]]:
"""Get the flows by reading the frontend_flows.yaml file."""
repo = get_repo(settings.frontend_flows_path.parent)

if build_id is not None:
tag = int(build_id)
try:
repo.git.checkout(tag, settings.frontend_flows_path.name)
except GitCommandError as e:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Build_id {tag} not found",
) from e
else:
try:
repo.git.checkout("HEAD", settings.frontend_flows_path.name)
except GitCommandError as e:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Failed to checkout the latest commit",
) from e

omega_flows = await read_conf(settings.frontend_flows_path)
dict_flows = OmegaConf.to_container(omega_flows, resolve=True)
return {"status": "ok", "data": dict_flows} # type: ignore
Expand All @@ -20,5 +46,24 @@ async def flows_get() -> Dict[str, Union[str, Dict[str, Union[list, dict]]]]:
@router.post("/")
async def flows_post(flows: Dict[str, Union[list, dict]]) -> Dict[str, str]:
"""Write the flows to the frontend_flows.yaml file."""
logger = get_logger(__name__)
repo = get_repo(settings.frontend_flows_path.parent)

tags = sorted(repo.tags, key=lambda t: t.commit.committed_datetime)
repo.git.checkout(tags[-1], settings.frontend_flows_path.name)

await write_conf(flows, settings.frontend_flows_path)
logger.info("Flows saved to DB")

commit_changes(repo, "Save frontend flows")

return {"status": "ok"}


@router.post("/tg_token")
async def post_tg_token(token: str):
dotenv_path = Path(settings.work_directory) / ".env"
dotenv_path.touch(exist_ok=True)

set_key(dotenv_path, "TG_BOT_TOKEN", token)
return {"status": "ok", "message": "Token saved successfully"}
21 changes: 1 addition & 20 deletions backend/chatsky_ui/api/deps.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from chatsky_ui.core.config import settings
from chatsky_ui.services.index import Index
from chatsky_ui.services.process_manager import BuildManager, RunManager
from chatsky_ui.services.websocket_manager import WebSocketManager


build_manager = BuildManager()

Expand All @@ -17,20 +15,3 @@ def get_build_manager() -> BuildManager:
def get_run_manager() -> RunManager:
run_manager.set_logger()
return run_manager


websocket_manager = WebSocketManager()


def get_websocket_manager() -> WebSocketManager:
websocket_manager.set_logger()
return websocket_manager


index = Index()


def get_index() -> Index:
index.set_logger()
index.set_path(settings.index_path)
return index
Loading
Loading