cycls 0.0.2.14__py3-none-any.whl → 0.0.2.20__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
cycls/__init__.py CHANGED
@@ -1 +1 @@
1
- from .cycls import Cycls, Text, Message
1
+ from .cycls import Cycls
cycls/cycls.py CHANGED
@@ -10,6 +10,8 @@ import inspect
10
10
  import logging
11
11
  logging.basicConfig(level=logging.ERROR)
12
12
 
13
+ O = lambda x,y: print(f"✦/✧ {str(x).ljust(7)} | {y}")
14
+
13
15
  import os
14
16
  current_dir = os.path.dirname(os.path.abspath(__file__))
15
17
  key_path = os.path.join(current_dir, 'tuns')
@@ -20,6 +22,7 @@ class Message(BaseModel):
20
22
  id: str
21
23
  history: Optional[List[Dict[str, str]]] = None
22
24
 
25
+ #!
23
26
  def find_available_port(start_port):
24
27
  port = start_port
25
28
  while True:
@@ -29,39 +32,34 @@ def find_available_port(start_port):
29
32
  port += 1
30
33
 
31
34
  import asyncssh, asyncio
32
-
33
35
  async def create_ssh_tunnel(x,y,z='tuns.sh'):
34
36
  try:
35
37
  async with asyncssh.connect(z,client_keys=[key_path],known_hosts=None) as conn:
36
38
  listener = await conn.forward_remote_port(x, 80, 'localhost', y)
37
- print("✦/✧","tunnel\n")
39
+ O("tunnel","open");print(" ")
38
40
  await listener.wait_closed()
39
41
  except (OSError, asyncssh.Error) as e:
40
- print("✦/✧",f"tunnel disconnected: {e}")
42
+ O("tunnel",f"disconnected ({e})")
41
43
 
42
- def register(handles, network, url, mode):
44
+ def register(handles, graph, url, mode):
43
45
  try:
44
46
  with httpx.Client() as client:
45
- response = client.post(f"{network}/register", json={"handles":handles, "url":url, "mode":mode})
47
+ response = client.post(f"{graph}/register", json={"handles":handles, "url":url, "mode":mode})
46
48
  if response.status_code==200:
47
49
  data = (response.json()).get("content")
48
- for i in data:print(f"✦/✧ {i[0]} / {network}/{i[1]}")
50
+ for i in data:
51
+ O(i[0],f"{graph}/{i[1]}")
49
52
  else:
50
53
  print("✦/✧ failed to register ⚠️")
51
54
  except Exception as e:
52
55
  print(f"An error occurred: {e}")
53
56
 
54
- async def run_server(x,y):
55
- config = uvicorn.Config(x, host="127.0.0.1", port=y, log_level="error")
56
- server = uvicorn.Server(config)
57
- await server.serve()
58
-
59
57
  class Cycls:
60
- def __init__(self, url="", network="https://cycls.com", port=find_available_port(8001)):
58
+ def __init__(self, url="", graph="https://cycls.com", port=find_available_port(8001)):
61
59
  import uuid
62
60
  self.subdomain = str(uuid.uuid4())[:8]
63
61
  self.server = FastAPI()
64
- self.network = network
62
+ self.graph = graph
65
63
  self.port = port
66
64
  self.url = url
67
65
  self.apps = {}
@@ -70,12 +68,12 @@ class Cycls:
70
68
  def decorator(func):
71
69
  @wraps(func)
72
70
  async def async_wrapper(*args, **kwargs):
73
- return await func(*args, **kwargs)
71
+ return StreamingResponse(await func(*args, **kwargs))
74
72
  @wraps(func)
75
73
  def sync_wrapper(*args, **kwargs):
76
- return func(*args, **kwargs)
74
+ return StreamingResponse(func(*args, **kwargs))
77
75
  wrapper = async_wrapper if inspect.iscoroutinefunction(func) else sync_wrapper
78
- self.apps["@"+handle] = wrapper
76
+ self.apps[handle] = wrapper
79
77
  return wrapper
80
78
  return decorator
81
79
 
@@ -90,27 +88,42 @@ class Cycls:
90
88
 
91
89
  def push(self):
92
90
  self.server.post("/gateway")(self.gateway)
93
- asyncio.run(self.publish())
91
+ @self.server.on_event("startup")
92
+ def startup_event():
93
+ asyncio.create_task(create_ssh_tunnel(f"{self.subdomain}-cycls", self.port))
94
+
95
+ self.publish()
94
96
 
95
- async def publish(self):
97
+ try:
98
+ uvicorn.run(self.server, host="127.0.0.1", port=self.port, log_level="error")
99
+ except KeyboardInterrupt:
100
+ print(" ");O("exit","done")
101
+
102
+ def publish(self):
103
+ #!
96
104
  prod=False
97
105
  if self.url != "":
98
106
  prod=True
99
107
 
100
- print(f"✦/✧ serving at port: {self.port}")
108
+ O("port",self.port)
101
109
  if prod:
102
- print("✦/✧",f"production mode | url: {self.url}")
103
- register(list(self.apps.keys()), self.network, self.url+"/gateway", "prod")
110
+ O("mode",f"production (url:{self.url})")
111
+ register(list(self.apps.keys()), self.graph, self.url+"/gateway", "prod")
104
112
  else:
105
113
  self.url = f"http://{self.subdomain}-cycls.tuns.sh"
106
- print("✦/✧","development mode")
107
- # print("✦/✧",f"url {self.url}")
108
- register(list(self.apps.keys()), self.network, self.url+"/gateway", "dev")
109
-
110
- t1 = asyncio.create_task(create_ssh_tunnel(f"{self.subdomain}-cycls", self.port))
111
- t2 = asyncio.create_task(run_server(self.server,self.port))
112
- await asyncio.gather(t1, t2) if not prod else asyncio.gather(t2)
113
-
114
- Text = StreamingResponse
115
-
114
+ O("mode","development")
115
+ register(list(self.apps.keys()), self.graph, self.url+"/gateway", "dev")
116
+
117
+ async def call(self, handle, content):
118
+ data = {"handle":handle, "content":content, "session":{}, "agent":"yes"}
119
+ try:
120
+ url = f"{self.graph}/stream/"
121
+ async with httpx.AsyncClient(timeout=20) as client, client.stream("POST", url, json=data) as response:
122
+ if response.status_code != 200:
123
+ print("http error")
124
+ async for token in response.aiter_text():
125
+ yield token
126
+ except Exception as e:
127
+ print("Exception", e)
128
+
116
129
  # poetry publish --build
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cycls
3
- Version: 0.0.2.14
3
+ Version: 0.0.2.20
4
4
  Summary: Cycls SDK
5
5
  Author: Mohammed Jamal
6
6
  Author-email: mj@cycls.com
@@ -34,31 +34,35 @@ pip install cycls
34
34
  ```
35
35
 
36
36
  ```py
37
- from cycls import Cycls, Text
37
+ from cycls import Cycls
38
38
 
39
39
  cycls = Cycls()
40
40
 
41
41
  # sync app on https://cycls.com/@spark
42
- @cycls("spark")
43
- def spark_app(x):
44
- print("history", x.history)
45
- print("session id", x.id)
46
- return Text(x.content+" from spark")
42
+ @cycls("@spark")
43
+ def spark_app(message):
44
+ print("history", message.history)
45
+ print("session id", message.id)
46
+ return message.content + "from spark"
47
47
 
48
48
  # async app on https://cycls.com/@cake
49
- @cycls("cake")
50
- async def cake_app(x):
51
- print("history", x.history)
52
- print("session id", x.id)
53
- return Text(x.content+" from cake")
49
+ @cycls("@cake")
50
+ async def cake_app(message):
51
+ print("history", message.history)
52
+ print("session id", message.id)
53
+ return message.content + "from cake"
54
54
 
55
55
  # publish to https://cycls.com
56
56
  cycls.push()
57
57
  ```
58
58
 
59
- - `Text` renders markdown
60
- - `Text` is both streaming/bulk based on input
59
+ Return a string. Supports markdown. Supports generators for streaming responses.
61
60
 
61
+ try it live
62
+ - https://cycls.com/@groq
63
+ - https://cycls.com/@openai
62
64
 
63
- Try it live https://cycls.com/@groq
65
+ code examples
66
+ - https://github.com/Cycls/examples/blob/main/groq.py
67
+ - https://github.com/Cycls/examples/blob/main/openai.py
64
68
 
@@ -0,0 +1,6 @@
1
+ cycls/__init__.py,sha256=HPPQikt_Trbc4s8XyEOeOjB_JRWXlXIkJuh762nUM_g,24
2
+ cycls/cycls.py,sha256=gX5PFNjZInAskntiBZzTVVpe9Ao4TeBZtoQWO4sIm3I,4459
3
+ cycls/tuns,sha256=CT8olxDKOM0cY6r_bbSGtnWyEmEYFVDVHj9ug3gbYHk,1843
4
+ cycls-0.0.2.20.dist-info/METADATA,sha256=snXPqTdCtw6JM6x8MqsviRYRgBf4V6xdydcU5wvkMYQ,2020
5
+ cycls-0.0.2.20.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
6
+ cycls-0.0.2.20.dist-info/RECORD,,
@@ -1,6 +0,0 @@
1
- cycls/__init__.py,sha256=mBBqS9LS550Uqluyxs7VdD1W-9sDkQfwqeX681PNiis,39
2
- cycls/cycls.py,sha256=6LoGg4q5__AsTBHEfdctjoXXIzrwo3veRKaBdpwBd8M,4032
3
- cycls/tuns,sha256=CT8olxDKOM0cY6r_bbSGtnWyEmEYFVDVHj9ug3gbYHk,1843
4
- cycls-0.0.2.14.dist-info/METADATA,sha256=rZejL67T3wGlc3XRsjBedhIyDbsnOOg-zvEKE2gQNd0,1824
5
- cycls-0.0.2.14.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
6
- cycls-0.0.2.14.dist-info/RECORD,,