cycls 0.0.2.20__py3-none-any.whl → 0.0.2.22__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/cycls.py CHANGED
@@ -10,7 +10,7 @@ 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}")
13
+ O = lambda x,y: print(f"✦/✧ {str(x).ljust(11)} | {y}")
14
14
 
15
15
  import os
16
16
  current_dir = os.path.dirname(os.path.abspath(__file__))
@@ -38,31 +38,34 @@ async def create_ssh_tunnel(x,y,z='tuns.sh'):
38
38
  listener = await conn.forward_remote_port(x, 80, 'localhost', y)
39
39
  O("tunnel","open");print(" ")
40
40
  await listener.wait_closed()
41
+ O("tunnel", "closed")
41
42
  except (OSError, asyncssh.Error) as e:
42
43
  O("tunnel",f"disconnected ({e})")
43
44
 
44
- def register(handles, graph, url, mode):
45
+ def register(handles, net, url, email):
45
46
  try:
46
47
  with httpx.Client() as client:
47
- response = client.post(f"{graph}/register", json={"handles":handles, "url":url, "mode":mode})
48
+ response = client.post(f"{net}/register", json={"handles":handles, "url":url, "email":email})
48
49
  if response.status_code==200:
49
50
  data = (response.json()).get("content")
50
51
  for i in data:
51
- O(i[0],f"{graph}/{i[1]}")
52
+ O(i[0],f"{net}/{i[1]}")
52
53
  else:
53
54
  print("✦/✧ failed to register ⚠️")
54
55
  except Exception as e:
55
56
  print(f"An error occurred: {e}")
56
57
 
57
58
  class Cycls:
58
- def __init__(self, url="", graph="https://cycls.com", port=find_available_port(8001)):
59
+ def __init__(self, url="", net="https://cycls.com", port=find_available_port(8001), email=None):
59
60
  import uuid
60
61
  self.subdomain = str(uuid.uuid4())[:8]
61
62
  self.server = FastAPI()
62
- self.graph = graph
63
+ self.net = net
63
64
  self.port = port
64
65
  self.url = url
65
66
  self.apps = {}
67
+ self.prod = False
68
+ self.email = email
66
69
 
67
70
  def __call__(self, handle):
68
71
  def decorator(func):
@@ -73,7 +76,13 @@ class Cycls:
73
76
  def sync_wrapper(*args, **kwargs):
74
77
  return StreamingResponse(func(*args, **kwargs))
75
78
  wrapper = async_wrapper if inspect.iscoroutinefunction(func) else sync_wrapper
76
- self.apps[handle] = wrapper
79
+
80
+ if self.url != "": self.prod=True #!
81
+ if not self.prod:
82
+ self.apps[handle + "-dev"] = wrapper
83
+ else:
84
+ self.apps[handle] = wrapper
85
+
77
86
  return wrapper
78
87
  return decorator
79
88
 
@@ -87,37 +96,34 @@ class Cycls:
87
96
  return {"error": "Handle not found"}
88
97
 
89
98
  def push(self):
99
+ if self.email:
100
+ O("email",self.email)
101
+ O("port",self.port)
102
+ if self.prod:
103
+ O("mode",f"production @ {self.url}")
104
+ register(list(self.apps.keys()), self.net, self.url+"/gateway", self.email)
105
+ else:
106
+ self.url = f"http://{self.subdomain}-cycls.tuns.sh"
107
+ O("mode","development")
108
+ O("docs","for more information, visit https://github.com/Cycls/cycls-py")
109
+ register(list(self.apps.keys()), self.net, self.url+"/gateway", self.email)
110
+
90
111
  self.server.post("/gateway")(self.gateway)
91
112
  @self.server.on_event("startup")
92
113
  def startup_event():
93
- asyncio.create_task(create_ssh_tunnel(f"{self.subdomain}-cycls", self.port))
94
-
95
- self.publish()
96
-
114
+ if self.prod:
115
+ pass
116
+ else:
117
+ asyncio.create_task(create_ssh_tunnel(f"{self.subdomain}-cycls", self.port))
97
118
  try:
98
119
  uvicorn.run(self.server, host="127.0.0.1", port=self.port, log_level="error")
99
120
  except KeyboardInterrupt:
100
121
  print(" ");O("exit","done")
101
122
 
102
- def publish(self):
103
- #!
104
- prod=False
105
- if self.url != "":
106
- prod=True
107
-
108
- O("port",self.port)
109
- if prod:
110
- O("mode",f"production (url:{self.url})")
111
- register(list(self.apps.keys()), self.graph, self.url+"/gateway", "prod")
112
- else:
113
- self.url = f"http://{self.subdomain}-cycls.tuns.sh"
114
- O("mode","development")
115
- register(list(self.apps.keys()), self.graph, self.url+"/gateway", "dev")
116
-
117
123
  async def call(self, handle, content):
118
124
  data = {"handle":handle, "content":content, "session":{}, "agent":"yes"}
119
125
  try:
120
- url = f"{self.graph}/stream/"
126
+ url = f"{self.net}/stream/"
121
127
  async with httpx.AsyncClient(timeout=20) as client, client.stream("POST", url, json=data) as response:
122
128
  if response.status_code != 200:
123
129
  print("http error")
@@ -0,0 +1,92 @@
1
+ Metadata-Version: 2.1
2
+ Name: cycls
3
+ Version: 0.0.2.22
4
+ Summary: Cycls SDK
5
+ Author: Mohammed Jamal
6
+ Author-email: mj@cycls.com
7
+ Requires-Python: >=3.8,<4.0
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.8
10
+ Classifier: Programming Language :: Python :: 3.9
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Requires-Dist: asyncssh (>=2.14.2,<3.0.0)
15
+ Requires-Dist: fastapi (>=0.111.0,<0.112.0)
16
+ Requires-Dist: httpx (>=0.27.0,<0.28.0)
17
+ Description-Content-Type: text/markdown
18
+
19
+ </br></br>
20
+ <p align="center">
21
+ <picture>
22
+ <source media="(prefers-color-scheme: dark)" srcset="https://cycls.com/static/assets/logo-gold.svg">
23
+ <source media="(prefers-color-scheme: light)" srcset="https://cycls.com/static/assets/logo.svg">
24
+ <img alt="Cycls" src="https://cycls.com/static/assets/logo.svg" width="150">
25
+ </picture>
26
+ </p>
27
+ </br></br>
28
+
29
+ <div align="center">
30
+ <a href="https://pypi.org/project/cycls/" target="_blank" rel="noopener noreferrer">
31
+ <img loading="lazy" src="https://img.shields.io/pypi/v/cycls.svg" alt="PyPI" class="img_ev3q" style="display: inline;">
32
+ </a>
33
+ <a href="https://discord.gg/BMnaMatDC7" target="_blank" rel="noopener noreferrer">
34
+ <img loading="lazy" src="https://img.shields.io/discord/1175782747164389466" alt="Discord" class="img_ev3q" style="display: inline;">
35
+ </a>
36
+ </div>
37
+
38
+ </br>
39
+
40
+ ```sh
41
+ pip install cycls
42
+ ```
43
+
44
+ # Apps ✦
45
+ Instantly publish and share AI apps
46
+
47
+ ```py
48
+ from cycls import Cycls
49
+
50
+ cycls = Cycls()
51
+
52
+ @cycls("@spark")
53
+ def app(x):
54
+ return x.content + "from spark"
55
+
56
+ cycls.push()
57
+ ```
58
+ `cycls.push()` will then publish the app `@spark` on [cycls.com/@spark](https://cycls.com/@spark)
59
+ ## Async Apps
60
+ For performance, make the function asynchronous. The following is an async app with message `history` and session `id`
61
+ ```py
62
+ from cycls import Cycls
63
+
64
+ cycls = Cycls()
65
+
66
+ @cycls("@spark")
67
+ async def app(x):
68
+ print(x.history, x.id)
69
+ return x.content + "from spark"
70
+
71
+ cycls.push()
72
+ ```
73
+
74
+ # Agents ✧
75
+ Call any public app as an agent, see [explore](https://explore.cycls.com)
76
+ ```py
77
+ from cycls import Cycls
78
+
79
+ cycls = Cycls()
80
+
81
+ @cycls("@spark")
82
+ async def app(x):
83
+ return cycls.call("@groq",
84
+ x.content)
85
+
86
+ cycls.push()
87
+ ```
88
+
89
+ ### Try it live
90
+ - [cycls.com/@groq](https://cycls.com/@groq) | [groq.py](https://github.com/Cycls/examples/blob/main/groq.py)
91
+ - [cycls.com/@openai](https://cycls.com/@openai) | [openai.py](https://github.com/Cycls/examples/blob/main/openai.py)
92
+
@@ -0,0 +1,6 @@
1
+ cycls/__init__.py,sha256=HPPQikt_Trbc4s8XyEOeOjB_JRWXlXIkJuh762nUM_g,24
2
+ cycls/cycls.py,sha256=GVC6IJ9AhKjNY5KA_osP2mbWjlDdymkWNNQuyQ6a8jA,4794
3
+ cycls/tuns,sha256=CT8olxDKOM0cY6r_bbSGtnWyEmEYFVDVHj9ug3gbYHk,1843
4
+ cycls-0.0.2.22.dist-info/METADATA,sha256=rWDwf1rez9xYZnLOh3o5C8osTajOrC3CIvyyyT2IliU,2593
5
+ cycls-0.0.2.22.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
6
+ cycls-0.0.2.22.dist-info/RECORD,,
@@ -1,68 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: cycls
3
- Version: 0.0.2.20
4
- Summary: Cycls SDK
5
- Author: Mohammed Jamal
6
- Author-email: mj@cycls.com
7
- Requires-Python: >=3.8,<4.0
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: Programming Language :: Python :: 3.8
10
- Classifier: Programming Language :: Python :: 3.9
11
- Classifier: Programming Language :: Python :: 3.10
12
- Classifier: Programming Language :: Python :: 3.11
13
- Classifier: Programming Language :: Python :: 3.12
14
- Requires-Dist: asyncssh (>=2.14.2,<3.0.0)
15
- Requires-Dist: fastapi (>=0.111.0,<0.112.0)
16
- Requires-Dist: httpx (>=0.27.0,<0.28.0)
17
- Description-Content-Type: text/markdown
18
-
19
- </br></br><p align="center"><img src="https://cycls.com/static/assets/favicon.svg" alt="Cycls"></p></br>
20
-
21
- <div align="center">
22
- <a href="https://pypi.org/project/cycls/" target="_blank" rel="noopener noreferrer">
23
- <img loading="lazy" src="https://img.shields.io/pypi/v/cycls.svg" alt="PyPI" class="img_ev3q" style="display: inline;">
24
- </a>
25
- <a href="https://discord.gg/BMnaMatDC7" target="_blank" rel="noopener noreferrer">
26
- <img loading="lazy" src="https://img.shields.io/discord/1175782747164389466" alt="Discord" class="img_ev3q" style="display: inline;">
27
- </a>
28
- </div>
29
-
30
- </br>
31
-
32
- ```sh
33
- pip install cycls
34
- ```
35
-
36
- ```py
37
- from cycls import Cycls
38
-
39
- cycls = Cycls()
40
-
41
- # sync app on https://cycls.com/@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
-
48
- # async app on https://cycls.com/@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
-
55
- # publish to https://cycls.com
56
- cycls.push()
57
- ```
58
-
59
- Return a string. Supports markdown. Supports generators for streaming responses.
60
-
61
- try it live
62
- - https://cycls.com/@groq
63
- - https://cycls.com/@openai
64
-
65
- code examples
66
- - https://github.com/Cycls/examples/blob/main/groq.py
67
- - https://github.com/Cycls/examples/blob/main/openai.py
68
-
@@ -1,6 +0,0 @@
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,,