commit 81511072c6be1d2c93b029e548d55c46102956f5 Author: retoor <retoor@molodetz.nl> Date: Tue Dec 3 17:52:00 2024 +0100 New build. diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml new file mode 100644 index 0000000..48d3cb2 --- /dev/null +++ b/.gitea/workflows/build.yaml @@ -0,0 +1,26 @@ +name: Build package +run-name: Build package +on: [push] + +jobs: + Build: + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v4 + - name: Update repo + run: git pull + - name: List files in the repository + run: | + ls ${{ gitea.workspace }} + - name: Update apt + run: apt update + - name: Installing system dependencies + run: apt install python3 python3-pip python3-venv make -y + - name: Run Make + run: make + - run: git add . + - run: git config --global user.email "bot@molodetz.com" + - run: git config --global user.name "bot" + - run: git commit -a -m "Automated update of new package." + - run: git push diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a501307 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.vscode +.venv +.history +__pycache__ + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3aa9ff7 --- /dev/null +++ b/Makefile @@ -0,0 +1,24 @@ +BIN = ./.venv/bin/ +PYTHON = ./.venv/bin/python +PIP = ./.venv/bin/pip + +all: build + +ensure_env: + -@python3 -m venv .venv + +format: ensure_env + $(PIP) install shed + . $(BIN)/activate && shed + +build: format + $(PIP) install -e . + $(PIP) install build + $(PYTHON) -m build + +serve: ensure_env + $(BIN)rbabel.serve --host=0.0.0.0 --port=3011 --url=wss://flock.molodetz.nl + +bench: ensure_env + $(BIN)rbabel.bench --url=http://localhost:3011/ + diff --git a/dist/Rbabel-1.3.37-py3-none-any.whl b/dist/Rbabel-1.3.37-py3-none-any.whl new file mode 100644 index 0000000..754a056 Binary files /dev/null and b/dist/Rbabel-1.3.37-py3-none-any.whl differ diff --git a/dist/rbabel-1.0.0-py3-none-any.whl b/dist/rbabel-1.0.0-py3-none-any.whl new file mode 100644 index 0000000..5630668 Binary files /dev/null and b/dist/rbabel-1.0.0-py3-none-any.whl differ diff --git a/dist/rbabel-1.0.0.tar.gz b/dist/rbabel-1.0.0.tar.gz new file mode 100644 index 0000000..4d17259 Binary files /dev/null and b/dist/rbabel-1.0.0.tar.gz differ diff --git a/dist/rbabel-1.3.37-py3-none-any.whl b/dist/rbabel-1.3.37-py3-none-any.whl new file mode 100644 index 0000000..934488b Binary files /dev/null and b/dist/rbabel-1.3.37-py3-none-any.whl differ diff --git a/dist/rbabel-1.3.37.tar.gz b/dist/rbabel-1.3.37.tar.gz new file mode 100644 index 0000000..3afa8a0 Binary files /dev/null and b/dist/rbabel-1.3.37.tar.gz differ diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..07de284 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..fd96aea --- /dev/null +++ b/setup.cfg @@ -0,0 +1,28 @@ +[metadata] +name = rbabel +version = 1.0.0 +description = English sentence corrector +author = Retoor +author_email = retoor@molodetz.nl +license = MIT +long_description = file: README.md +long_description_content_type = text/markdown + +[options] +packages = find: +package_dir = + = src +python_requires = >=3.7 +install_requires = + aiohttp + dataset + yura @ git+https://retoor.molodetz.nl/retoor/yura.git@main + +[options.packages.find] +where = src + +[options.entry_points] +console_scripts = + rbabel.serve = rbabel.__main__:main + rbabel.bench = rbabel.cli:cli_bench + rbabel = rbabel.cli:main diff --git a/src/Rbabel.egg-info/PKG-INFO b/src/Rbabel.egg-info/PKG-INFO new file mode 100644 index 0000000..e6be732 --- /dev/null +++ b/src/Rbabel.egg-info/PKG-INFO @@ -0,0 +1,12 @@ +Metadata-Version: 2.1 +Name: Rbabel +Version: 1.3.37 +Summary: English sentence corrector +Author: Retoor +Author-email: retoor@molodetz.nl +License: MIT +Requires-Python: >=3.7 +Description-Content-Type: text/markdown +Requires-Dist: aiohttp +Requires-Dist: dataset +Requires-Dist: yura@ git+https://retoor.molodetz.nl/retoor/yura.git@main diff --git a/src/Rbabel.egg-info/SOURCES.txt b/src/Rbabel.egg-info/SOURCES.txt new file mode 100644 index 0000000..a98f322 --- /dev/null +++ b/src/Rbabel.egg-info/SOURCES.txt @@ -0,0 +1,13 @@ +pyproject.toml +setup.cfg +src/Rbabel.egg-info/PKG-INFO +src/Rbabel.egg-info/SOURCES.txt +src/Rbabel.egg-info/dependency_links.txt +src/Rbabel.egg-info/entry_points.txt +src/Rbabel.egg-info/requires.txt +src/Rbabel.egg-info/top_level.txt +src/rbabel/__init__.py +src/rbabel/__main__.py +src/rbabel/app.py +src/rbabel/args.py +src/rbabel/cli.py \ No newline at end of file diff --git a/src/Rbabel.egg-info/dependency_links.txt b/src/Rbabel.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/Rbabel.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/src/Rbabel.egg-info/entry_points.txt b/src/Rbabel.egg-info/entry_points.txt new file mode 100644 index 0000000..c731308 --- /dev/null +++ b/src/Rbabel.egg-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +rbabel = rbabel.cli:main +rbabel.serve = rbabel.__main__:main diff --git a/src/Rbabel.egg-info/requires.txt b/src/Rbabel.egg-info/requires.txt new file mode 100644 index 0000000..d179af3 --- /dev/null +++ b/src/Rbabel.egg-info/requires.txt @@ -0,0 +1,3 @@ +aiohttp +dataset +yura@ git+https://retoor.molodetz.nl/retoor/yura.git@main diff --git a/src/Rbabel.egg-info/top_level.txt b/src/Rbabel.egg-info/top_level.txt new file mode 100644 index 0000000..08daaf4 --- /dev/null +++ b/src/Rbabel.egg-info/top_level.txt @@ -0,0 +1 @@ +rbabel diff --git a/src/rbabel.egg-info/PKG-INFO b/src/rbabel.egg-info/PKG-INFO new file mode 100644 index 0000000..a0ebe06 --- /dev/null +++ b/src/rbabel.egg-info/PKG-INFO @@ -0,0 +1,12 @@ +Metadata-Version: 2.1 +Name: rbabel +Version: 1.0.0 +Summary: English sentence corrector +Author: Retoor +Author-email: retoor@molodetz.nl +License: MIT +Requires-Python: >=3.7 +Description-Content-Type: text/markdown +Requires-Dist: aiohttp +Requires-Dist: dataset +Requires-Dist: yura@ git+https://retoor.molodetz.nl/retoor/yura.git@main diff --git a/src/rbabel.egg-info/SOURCES.txt b/src/rbabel.egg-info/SOURCES.txt new file mode 100644 index 0000000..eadca91 --- /dev/null +++ b/src/rbabel.egg-info/SOURCES.txt @@ -0,0 +1,13 @@ +pyproject.toml +setup.cfg +src/rbabel/__init__.py +src/rbabel/__main__.py +src/rbabel/app.py +src/rbabel/args.py +src/rbabel/cli.py +src/rbabel.egg-info/PKG-INFO +src/rbabel.egg-info/SOURCES.txt +src/rbabel.egg-info/dependency_links.txt +src/rbabel.egg-info/entry_points.txt +src/rbabel.egg-info/requires.txt +src/rbabel.egg-info/top_level.txt \ No newline at end of file diff --git a/src/rbabel.egg-info/dependency_links.txt b/src/rbabel.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/rbabel.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/src/rbabel.egg-info/entry_points.txt b/src/rbabel.egg-info/entry_points.txt new file mode 100644 index 0000000..be7cc35 --- /dev/null +++ b/src/rbabel.egg-info/entry_points.txt @@ -0,0 +1,4 @@ +[console_scripts] +rbabel = rbabel.cli:main +rbabel.bench = rbabel.cli:cli_bench +rbabel.serve = rbabel.__main__:main diff --git a/src/rbabel.egg-info/requires.txt b/src/rbabel.egg-info/requires.txt new file mode 100644 index 0000000..d179af3 --- /dev/null +++ b/src/rbabel.egg-info/requires.txt @@ -0,0 +1,3 @@ +aiohttp +dataset +yura@ git+https://retoor.molodetz.nl/retoor/yura.git@main diff --git a/src/rbabel.egg-info/top_level.txt b/src/rbabel.egg-info/top_level.txt new file mode 100644 index 0000000..08daaf4 --- /dev/null +++ b/src/rbabel.egg-info/top_level.txt @@ -0,0 +1 @@ +rbabel diff --git a/src/rbabel/__init__.py b/src/rbabel/__init__.py new file mode 100644 index 0000000..7e315cc --- /dev/null +++ b/src/rbabel/__init__.py @@ -0,0 +1,9 @@ +import logging + +logging.basicConfig( + level=logging.DEBUG, + format='%(asctime)s - %(levelname)s - %(message)s', + datefmt='%Y-%m-%d %H:%M:%S' +) + +log = logging.getLogger(__name__) diff --git a/src/rbabel/__main__.py b/src/rbabel/__main__.py new file mode 100644 index 0000000..23d38fd --- /dev/null +++ b/src/rbabel/__main__.py @@ -0,0 +1,13 @@ +from aiohttp import web +from rbabel.app import create_app +from rbabel.args import parse_args + +def main(): + args = parse_args() + app = create_app(args.url) + web.run_app(app,host=args.host,port=args.port) + + +if __name__ == '__main__': + nain() + diff --git a/src/rbabel/app.py b/src/rbabel/app.py new file mode 100644 index 0000000..216f8a2 --- /dev/null +++ b/src/rbabel/app.py @@ -0,0 +1,50 @@ +from aiohttp import web +from yura.client import AsyncClient as LLMClient + +from rbabel import log + +LLM_NAME = "rbabel" +LLM_CONTEXT = "You are an English grammar corrector. You repsond with only the corrected English of by user given prompt and nothing more. Also replace numbers with the word variant." +LLM_MODEL = "gemma2:latest" + +class Application(web.Application): + + + def __init__(self, llm_url=None, llm_name=LLM_NAME, llm_model=LLM_MODEL,llm_context=LLM_CONTEXT, *args, **kwargs): + self.llm_url = llm_url + self.llm_name = llm_name + self.llm_model = LLM_MODEL + self.llm_context = llm_context + super().__init__(*args, **kwargs) + self.on_startup.append(self.create_llm) + self.router.add_post("/", self.optimize_grammar_handler) + + async def create_llm(self, app): + llm_client = LLMClient(self.llm_url) + log.info("Creating LLM named {}.".format(self.llm_name)) + success = await llm_client.create(self.llm_name, self.llm_model, self.llm_context) + assert(success) + log.info("LLM {} created.".format(self.llm_name)) + await llm_client.close() + + async def fix_grammar(self, content): + corrected_content = [] + llm_client = LLMClient(self.llm_url) + token = await llm_client.connect(self.llm_name) + async for chunk in llm_client.chat(token, content): + corrected_content.append(chunk['content']) + await llm_client.close() + return "".join(corrected_content) + + async def optimize_grammar_handler(self,request): + text = await request.json() + assert(type(text) ==str) + corrected = await self.fix_grammar(text) + print("was:",text) + print("became:",corrected) + return web.json_response(corrected,content_type="application/json") + + +def create_app(llm_url): + return Application(llm_url, LLM_NAME, LLM_MODEL, LLM_CONTEXT) + diff --git a/src/rbabel/args.py b/src/rbabel/args.py new file mode 100644 index 0000000..6277288 --- /dev/null +++ b/src/rbabel/args.py @@ -0,0 +1,35 @@ +import argparse + +def parse_args(): + parser = argparse.ArgumentParser( + description="AI enabled English corrector. Only minor improvements." + ) + + parser.add_argument( + '--url', + type=str, + required=False, + default="http://127.0.0.1:3011/", + help='URL of Katya LLM Server.' + ) + + parser.add_argument( + '--host', + type=str, + default="127.0.0.1", + required=False, + help='Host to bind to.' + ) + + + parser.add_argument( + '--port', + type=int, + default=3011, + required=False, + help='Port to bind to.' + ) + + return parser.parse_args() + + diff --git a/src/rbabel/cli.py b/src/rbabel/cli.py new file mode 100644 index 0000000..865c918 --- /dev/null +++ b/src/rbabel/cli.py @@ -0,0 +1,50 @@ +import asyncio +from aiohttp import ClientSession +from rbabel.args import parse_args +import time + + +async def cli_client(url): + + while True: + sentence = input("> ") + async with ClientSession() as session: + async with session.post("http://localhost:8080",json=sentence) as response: + try: + print(await response.json()) + except Exception as ex: + print(ex) + print(await response.text()) + +async def bench(url): + index = 0 + while True: + index += 1 + sentence = "I bougt {} woden shoe".format(index) + time_start = time.time() + async with ClientSession() as session: + async with session.post(url,json=sentence) as response: + try: + print(await response.json()) + except Exception as ex: + print(ex) + print(await response.text()) + time_end = time.time() + print("Duration: {}".format(time_end-time_start)) + + +def cli_bench(): + args = parse_args() + asyncio.run(bench(args.url)) + + +def main(): + args = parse_args() + asyncio.run(cli_client(args.url)) + +if __name__ == '__main__': + main() + + + +