Initial commit
This commit is contained in:
commit
1cbf5ae4d3
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.venv
|
||||
__*
|
BIN
dist/yura-13.3.7-py3-none-any.whl
vendored
Normal file
BIN
dist/yura-13.3.7-py3-none-any.whl
vendored
Normal file
Binary file not shown.
BIN
dist/yura-13.3.7.tar.gz
vendored
Normal file
BIN
dist/yura-13.3.7.tar.gz
vendored
Normal file
Binary file not shown.
16
make
Executable file
16
make
Executable file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env python3
|
||||
import pathlib
|
||||
import os
|
||||
import sys
|
||||
|
||||
if not pathlib.Path(".venv").exists():
|
||||
os.system("python3 -m venv .venv")
|
||||
|
||||
if "build" in sys.argv:
|
||||
os.system("./.venv/bin/python -m pip install build")
|
||||
os.system("./.venv/bin/python -m build .")
|
||||
os.system("./.venv/bin/python -m pip install black")
|
||||
os.system("./.venv/bin/python -m black .")
|
||||
|
||||
|
||||
|
3
pyproject.toml
Normal file
3
pyproject.toml
Normal file
@ -0,0 +1,3 @@
|
||||
[build-system]
|
||||
requires = ["setuptools", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
27
setup.cfg
Normal file
27
setup.cfg
Normal file
@ -0,0 +1,27 @@
|
||||
[metadata]
|
||||
name = yura
|
||||
version = 13.3.7
|
||||
description = Yura async AI client
|
||||
author = retoor
|
||||
author_email = retoor@retoor.io
|
||||
license = MIT
|
||||
long_description = file: README.md
|
||||
long_description_content_type = text/markdown
|
||||
|
||||
[options]
|
||||
packages = find:
|
||||
include_package_data = true
|
||||
package_dir =
|
||||
= src
|
||||
python_requires = >=3.7
|
||||
install_requires =
|
||||
websockets
|
||||
[options.packages.find]
|
||||
where = src
|
||||
|
||||
[options.package_data]
|
||||
;stogram_client = binaries/*
|
||||
|
||||
[options.entry_points]
|
||||
console_scripts =
|
||||
yura = yura.client:main
|
10
src/yura.egg-info/PKG-INFO
Normal file
10
src/yura.egg-info/PKG-INFO
Normal file
@ -0,0 +1,10 @@
|
||||
Metadata-Version: 2.1
|
||||
Name: yura
|
||||
Version: 13.3.7
|
||||
Summary: Yura async AI client
|
||||
Author: retoor
|
||||
Author-email: retoor@retoor.io
|
||||
License: MIT
|
||||
Requires-Python: >=3.7
|
||||
Description-Content-Type: text/markdown
|
||||
Requires-Dist: websockets
|
8
src/yura.egg-info/SOURCES.txt
Normal file
8
src/yura.egg-info/SOURCES.txt
Normal file
@ -0,0 +1,8 @@
|
||||
pyproject.toml
|
||||
setup.cfg
|
||||
src/yura.egg-info/PKG-INFO
|
||||
src/yura.egg-info/SOURCES.txt
|
||||
src/yura.egg-info/dependency_links.txt
|
||||
src/yura.egg-info/entry_points.txt
|
||||
src/yura.egg-info/requires.txt
|
||||
src/yura.egg-info/top_level.txt
|
1
src/yura.egg-info/dependency_links.txt
Normal file
1
src/yura.egg-info/dependency_links.txt
Normal file
@ -0,0 +1 @@
|
||||
|
2
src/yura.egg-info/entry_points.txt
Normal file
2
src/yura.egg-info/entry_points.txt
Normal file
@ -0,0 +1,2 @@
|
||||
[console_scripts]
|
||||
yura = yura.client:main
|
1
src/yura.egg-info/requires.txt
Normal file
1
src/yura.egg-info/requires.txt
Normal file
@ -0,0 +1 @@
|
||||
websockets
|
1
src/yura.egg-info/top_level.txt
Normal file
1
src/yura.egg-info/top_level.txt
Normal file
@ -0,0 +1 @@
|
||||
|
106
src/yura/client.py
Normal file
106
src/yura/client.py
Normal file
@ -0,0 +1,106 @@
|
||||
import asyncio
|
||||
import websockets
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
class AsyncClient:
|
||||
|
||||
def __init__(self, url="ws://127.0.0.1:8470"):
|
||||
|
||||
self.url = url
|
||||
self.ws = None
|
||||
self.queue_in = asyncio.Queue()
|
||||
self.queue_out = asyncio.Queue()
|
||||
self.communication_task = None
|
||||
|
||||
async def ensure_connection():
|
||||
|
||||
if not self.ws:
|
||||
self.ws = await websockets.connect(self.url)
|
||||
|
||||
return self.ws
|
||||
|
||||
async def ensure_communication(self):
|
||||
|
||||
if not self.communication_task:
|
||||
self.communication_task = asyncio.create_task(self.communicate())
|
||||
|
||||
return self.communication_task
|
||||
|
||||
async def chat(self, message):
|
||||
await self.ensure_communication()
|
||||
await self.queue_out.put(message)
|
||||
while True:
|
||||
|
||||
while True:
|
||||
try:
|
||||
response = await asyncio.wait_for(self.queue_in.get(), 0.1)
|
||||
|
||||
except asyncio.TimeoutError:
|
||||
continue
|
||||
break
|
||||
|
||||
yield response
|
||||
|
||||
if response["done"]:
|
||||
break
|
||||
|
||||
async def communicate(self):
|
||||
loop = asyncio.get_event_loop()
|
||||
async with websockets.connect(self.url) as websocket:
|
||||
while True:
|
||||
message_content = None
|
||||
while not message_content:
|
||||
try:
|
||||
message_content = await asyncio.wait_for(
|
||||
self.queue_out.get(), 0.1
|
||||
)
|
||||
except asyncio.TimeoutError:
|
||||
continue
|
||||
|
||||
response = await websocket.send(json.dumps(message_content))
|
||||
|
||||
while True:
|
||||
response = json.loads(await websocket.recv())
|
||||
|
||||
if response["done"]:
|
||||
break
|
||||
|
||||
await self.queue_in.put(response)
|
||||
|
||||
await self.queue_in.put(response)
|
||||
|
||||
|
||||
async def cli_client(url="ws://127.0.0.1:8470"):
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
async_client = AsyncClient(url)
|
||||
|
||||
while True:
|
||||
|
||||
sys.stdout.write("> ")
|
||||
sys.stdout.flush()
|
||||
message_content = await loop.run_in_executor(None, sys.stdin.readline)
|
||||
|
||||
async for response in async_client.chat(message_content):
|
||||
|
||||
print(response["content"], end="", flush=True)
|
||||
|
||||
if response["done"]:
|
||||
break
|
||||
|
||||
print("")
|
||||
|
||||
|
||||
def main():
|
||||
url = "ws://127.0.0.1:8470"
|
||||
try:
|
||||
url = sys.argv[1]
|
||||
except IndexError:
|
||||
pass
|
||||
asyncio.run(cli_client(url))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in New Issue
Block a user