cycls 0.0.2.17__tar.gz → 0.0.2.20__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cycls
3
- Version: 0.0.2.17
3
+ Version: 0.0.2.20
4
4
  Summary: Cycls SDK
5
5
  Author: Mohammed Jamal
6
6
  Author-email: mj@cycls.com
@@ -39,14 +39,14 @@ from cycls import Cycls
39
39
  cycls = Cycls()
40
40
 
41
41
  # sync app on https://cycls.com/@spark
42
- @cycls("spark")
42
+ @cycls("@spark")
43
43
  def spark_app(message):
44
44
  print("history", message.history)
45
45
  print("session id", message.id)
46
46
  return message.content + "from spark"
47
47
 
48
48
  # async app on https://cycls.com/@cake
49
- @cycls("cake")
49
+ @cycls("@cake")
50
50
  async def cake_app(message):
51
51
  print("history", message.history)
52
52
  print("session id", message.id)
@@ -21,14 +21,14 @@ from cycls import Cycls
21
21
  cycls = Cycls()
22
22
 
23
23
  # sync app on https://cycls.com/@spark
24
- @cycls("spark")
24
+ @cycls("@spark")
25
25
  def spark_app(message):
26
26
  print("history", message.history)
27
27
  print("session id", message.id)
28
28
  return message.content + "from spark"
29
29
 
30
30
  # async app on https://cycls.com/@cake
31
- @cycls("cake")
31
+ @cycls("@cake")
32
32
  async def cake_app(message):
33
33
  print("history", message.history)
34
34
  print("session id", message.id)
@@ -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 = {}
@@ -75,7 +73,7 @@ class Cycls:
75
73
  def sync_wrapper(*args, **kwargs):
76
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,26 +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
- t1 = asyncio.create_task(create_ssh_tunnel(f"{self.subdomain}-cycls", self.port))
110
-
111
- t2 = asyncio.create_task(run_server(self.server,self.port))
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)
112
128
 
113
- await asyncio.gather(t1, t2) if not prod else await asyncio.gather(t2)
114
-
115
129
  # poetry publish --build
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "cycls"
3
- version = "0.0.2.17"
3
+ version = "0.0.2.20"
4
4
 
5
5
  packages = [{ include = "cycls" }]
6
6
  description = "Cycls SDK"
File without changes
File without changes