diff --git a/.gitea/workflows/deploy_via_docker_compose.yml b/.gitea/workflows/deploy_via_docker_compose.yml index dfa8058..7d8a29a 100644 --- a/.gitea/workflows/deploy_via_docker_compose.yml +++ b/.gitea/workflows/deploy_via_docker_compose.yml @@ -6,13 +6,13 @@ jobs: Explore-Gitea-Actions: #runs-on: ubuntu-latest steps: - - run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event." - - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!" + #- run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event." + #- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!" - name: List files in the repository run: | ls ~ - - run: echo "🍏 This job's status is ${{ job.status }}." + #- run: echo "🍏 This job's status is ${{ job.status }}." diff --git a/README.md b/README.md index 3ca968a..d6a3543 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,6 @@ sudo docker rmi $(sudo docker images -f "dangling=true" -q) Give just the translation of the given input to German and nothing else. -Give the JSON of a graph linking Germanys 9 biggest cities diff --git a/backend/Dockerfile b/backend/Dockerfile index bd7d40c..2657393 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -3,15 +3,19 @@ FROM python:3.12 RUN apt-get update RUN apt-get install -y firefox-esr RUN apt-get install -y ffmpeg -RUN apt-get install -y espeak-ng +RUN apt-get install -y espeak #RUN curl https://ollama.ai/install.sh | sh #RUN ollama run llama2 +WORKDIR /code + +COPY requirements.txt /code/requirements.txt +#RUN pip3 install --no-cache-dir --upgrade -r requirements.txt +RUN pip3 install --no-cache-dir -r requirements.txt + -COPY requirements.txt requirements.txt -RUN pip3 install -r requirements.txt COPY . . -ENTRYPOINT ["python3", "app.py"] +ENTRYPOINT ["python3", "/code/app.py"] #ENTRYPOINT ["fastapi", "run", "main.py", "--port", "8000"] diff --git a/backend/app.py b/backend/app.py index 1bfc9b8..5e7031e 100644 --- a/backend/app.py +++ b/backend/app.py @@ -6,33 +6,32 @@ OpenAPI access via http://localhost:5000/openapi/ on local docker-compose deploy #import warnings #warnings.filterwarnings("ignore") -#std lib modules: +#------std lib modules:------- import os, sys, json, time +import os.path from typing import Any, Tuple, List, Dict, Any, Callable, Optional from datetime import datetime, date from collections import namedtuple import hashlib, traceback, logging from functools import wraps +import base64 +#-------ext libs-------------- #llm from langchain.callbacks.manager import CallbackManager from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler -from langchain_community.llms import Ollama import tiktoken from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.chains import RetrievalQA +from langchain.callbacks.base import BaseCallbackHandler, BaseCallbackManager +from langchain.prompts import PromptTemplate - +from langchain_community.llms import Ollama from langchain_community.vectorstores.elasticsearch import ElasticsearchStore from langchain_community.document_loaders import PyPDFLoader, Docx2txtLoader from langchain_community.embeddings import OllamaEmbeddings - -from langchain.callbacks.base import BaseCallbackHandler, BaseCallbackManager -from langchain.prompts import PromptTemplate - -#ext libs from elasticsearch import NotFoundError, Elasticsearch # for normal read/write without vectors from elasticsearch_dsl import Search, A, Document, Date, Integer, Keyword, Float, Long, Text, connections from elasticsearch.exceptions import ConnectionError @@ -44,31 +43,24 @@ import jwt as pyjwt #flask, openapi -from flask import Flask, send_from_directory, Response, request, jsonify -import sys, os +from flask import Flask, send_from_directory, send_file, Response, request, jsonify from flask_cors import CORS, cross_origin from werkzeug.utils import secure_filename from flask_openapi3 import Info, Tag, OpenAPI, Server, FileStorage from flask_socketio import SocketIO, join_room, leave_room, rooms, send - -import base64 -import os from cryptography.fernet import Fernet from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC +import pyttsx3 + #----------home grown-------------- #from scraper import WebScraper from funcs import group_by from elastictools import get_by_id, update_by_id, delete_by_id from models import QueryLog, Chatbot, User -import pyttsx3 - -engine = pyttsx3.init() - - #LLM_PAYLOAD = int(os.getenv("LLM_PAYLOAD")) #CHUNK_SIZE = int(os.getenv("CHUNK_SIZE")) @@ -260,11 +252,13 @@ def handle_message(message): #try: room = message["room"] question = message["question"] + system_prompt = message["system_prompt"] bot_id = message["bot_id"] + #except: # return - for chunk in ask_bot(question, bot_id): + for chunk in ask_bot(system_prompt + " " + question, bot_id): socket.emit('backend token', {'data': chunk, "done": False}, to=room) socket.emit('backend token', {'done': True}, to=room) @@ -347,40 +341,56 @@ class GetSpeechRequest(BaseModel): @app.post('/text2speech', summary="", tags=[], security=security) @uses_jwt() def text2speech(form: GetSpeechRequest, decoded_jwt, user): + engine = pyttsx3.init() - #def get_voice(s): - # for v in engine.getProperty("voices"): - # if s == v.id: - # return v - - #def set_voice(v): - # engine.setProperty("voice", v.id) - - #def set_volume(n): - # engine.setProperty('volume', engine.getProperty('volume') + n) - - #def set_rate(n): - # engine.setProperty('rate', engine.getProperty('rate') + n) + def get_voice(s): + for v in engine.getProperty("voices"): + if s == v.id: + return v + def set_voice(v): + engine.setProperty("voice", v.id) + def set_volume(n): + engine.setProperty('volume', engine.getProperty('volume') + n) + def set_rate(n): + engine.setProperty('rate', engine.getProperty('rate') + n) #voices = engine.getProperty('voices') #engine.setProperty('voice', voices[1].id) - #set_voice(get_voice("english")) - #set_volume(-5.0) - #set_rate(-40) + set_voice(get_voice("english")) + set_volume(-5.0) + set_rate(-40) - # Speak the response - #engine.say(response) - #ngine.say("Hello World!") - #engine.say("Neuroscience!") + #espeak -v mb-en1 -s 120 "Hello world" + #sudo apt-get install mbrola mbrola-en1 + unix_timestamp = datetime.now().timestamp() + file_name = f'speech_{unix_timestamp}.mp3' + file_path = f'./public/{file_name}' - file_name = 'speech.mp3' - engine.save_to_file(form.text, file_name) + engine.save_to_file(form.text, file_path) engine.runAndWait() - return send_file(file_name) #, mimetype = 'zip', attachment_filename= 'Audiofiles.zip', as_attachment = True) + + timeout = 10 + t = 0 + step = 0.1 + while not os.path.isfile(file_path): + time.sleep(step) + t += step + if t > timeout: + raise Exception("Timeout(%s s) for creating speech.mp3!" % timeout) + + time.sleep(step) + + + #return send_file(file_path, mimetype='audio/mpeg') #, attachment_filename= 'Audiofiles.zip', as_attachment = True) + return jsonify({ + "status": "success", + "file": "/" + file_name + }) + diff --git a/backend/public/index.html b/backend/public/index.html index 2cfa6fb..f2d1a6d 100644 --- a/backend/public/index.html +++ b/backend/public/index.html @@ -144,6 +144,11 @@