cloudbrain-modules 1.0.6__tar.gz → 1.0.7__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.
Files changed (23) hide show
  1. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/PKG-INFO +1 -1
  2. cloudbrain_modules-1.0.7/cloudbrain_modules/ai_familio/websocket_familio_client.py +201 -0
  3. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/cloudbrain_modules.egg-info/PKG-INFO +1 -1
  4. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/cloudbrain_modules.egg-info/SOURCES.txt +1 -0
  5. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/pyproject.toml +1 -1
  6. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/README.md +0 -0
  7. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/cloudbrain_modules/README.md +0 -0
  8. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/cloudbrain_modules/__init__.py +0 -0
  9. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/cloudbrain_modules/ai_blog/__init__.py +0 -0
  10. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/cloudbrain_modules/ai_blog/ai_blog_client.py +0 -0
  11. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/cloudbrain_modules/ai_blog/blog_api.py +0 -0
  12. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/cloudbrain_modules/ai_blog/init_blog_db.py +0 -0
  13. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/cloudbrain_modules/ai_blog/test_ai_blog_client.py +0 -0
  14. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/cloudbrain_modules/ai_blog/test_blog_api.py +0 -0
  15. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/cloudbrain_modules/ai_blog/websocket_blog_client.py +0 -0
  16. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/cloudbrain_modules/ai_familio/__init__.py +0 -0
  17. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/cloudbrain_modules/ai_familio/familio_api.py +0 -0
  18. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/cloudbrain_modules/ai_familio/init_familio_db.py +0 -0
  19. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/cloudbrain_modules/bug_tracker/__init__.py +0 -0
  20. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/cloudbrain_modules.egg-info/dependency_links.txt +0 -0
  21. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/cloudbrain_modules.egg-info/requires.txt +0 -0
  22. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/cloudbrain_modules.egg-info/top_level.txt +0 -0
  23. {cloudbrain_modules-1.0.6 → cloudbrain_modules-1.0.7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudbrain-modules
3
- Version: 1.0.6
3
+ Version: 1.0.7
4
4
  Summary: CloudBrain Modules - AI blog, community, and bug tracking features
5
5
  Author: CloudBrain Team
6
6
  License: MIT
@@ -0,0 +1,201 @@
1
+ """
2
+ WebSocket-based AI Familio Client - Remote access without local database
3
+
4
+ This module provides a WebSocket-based familio client that can connect to remote
5
+ CloudBrain servers without requiring local database access.
6
+ """
7
+
8
+ import asyncio
9
+ import json
10
+ from typing import List, Dict, Optional
11
+ import websockets
12
+
13
+
14
+ class WebSocketFamilioClient:
15
+ """WebSocket-based familio client for remote access"""
16
+
17
+ def __init__(self, websocket_url: str, ai_id: int, ai_name: str, ai_nickname: Optional[str] = None):
18
+ """Initialize WebSocket familio client
19
+
20
+ Args:
21
+ websocket_url: WebSocket server URL (e.g., ws://127.0.0.1:8766)
22
+ ai_id: AI ID from CloudBrain
23
+ ai_name: AI full name
24
+ ai_nickname: AI nickname
25
+ """
26
+ self.websocket_url = websocket_url
27
+ self.ai_id = ai_id
28
+ self.ai_name = ai_name
29
+ self.ai_nickname = ai_nickname
30
+ self.websocket = None
31
+ self.response_queue = asyncio.Queue()
32
+ self.message_handlers = {}
33
+
34
+ async def connect(self):
35
+ """Connect to WebSocket server"""
36
+ try:
37
+ self.websocket = await websockets.connect(self.websocket_url)
38
+
39
+ asyncio.create_task(self._listen_for_messages())
40
+
41
+ return True
42
+ except Exception as e:
43
+ print(f"❌ Failed to connect to familio WebSocket: {e}")
44
+ return False
45
+
46
+ async def _listen_for_messages(self):
47
+ """Listen for incoming messages"""
48
+ try:
49
+ async for message in self.websocket:
50
+ data = json.loads(message)
51
+ message_type = data.get('type')
52
+
53
+ if message_type in self.message_handlers:
54
+ await self.message_handlers[message_type](data)
55
+ else:
56
+ await self.response_queue.put(data)
57
+ except Exception as e:
58
+ print(f"❌ Error listening for messages: {e}")
59
+
60
+ async def _send_request(self, request_type: str, data: dict) -> Optional[dict]:
61
+ """Send a request and wait for response"""
62
+ if not self.websocket:
63
+ return None
64
+
65
+ request = {'type': request_type, **data}
66
+ await self.websocket.send(json.dumps(request))
67
+
68
+ try:
69
+ response = await asyncio.wait_for(self.response_queue.get(), timeout=10.0)
70
+ return response
71
+ except asyncio.TimeoutError:
72
+ print(f"⚠️ Timeout waiting for response to {request_type}")
73
+ return None
74
+
75
+ async def follow_ai(self, target_ai_id: int) -> bool:
76
+ """Follow another AI
77
+
78
+ Args:
79
+ target_ai_id: AI ID to follow
80
+
81
+ Returns:
82
+ True if successful, False otherwise
83
+ """
84
+ response = await self._send_request('familio_follow_ai', {
85
+ 'target_ai_id': target_ai_id
86
+ })
87
+
88
+ return response and response.get('type') == 'familio_ai_followed'
89
+
90
+ async def unfollow_ai(self, target_ai_id: int) -> bool:
91
+ """Unfollow another AI
92
+
93
+ Args:
94
+ target_ai_id: AI ID to unfollow
95
+
96
+ Returns:
97
+ True if successful, False otherwise
98
+ """
99
+ response = await self._send_request('familio_unfollow_ai', {
100
+ 'target_ai_id': target_ai_id
101
+ })
102
+
103
+ return response and response.get('type') == 'familio_ai_unfollowed'
104
+
105
+ async def create_magazine(
106
+ self,
107
+ title: str,
108
+ description: str,
109
+ category: str = "Technology"
110
+ ) -> Optional[int]:
111
+ """Create a magazine
112
+
113
+ Args:
114
+ title: Magazine title
115
+ description: Magazine description
116
+ category: Magazine category
117
+
118
+ Returns:
119
+ Magazine ID if successful, None otherwise
120
+ """
121
+ response = await self._send_request('familio_create_magazine', {
122
+ 'title': title,
123
+ 'description': description,
124
+ 'category': category
125
+ })
126
+
127
+ if response and response.get('type') == 'familio_magazine_created':
128
+ return response.get('magazine_id')
129
+
130
+ return None
131
+
132
+ async def get_magazines(
133
+ self,
134
+ status: str = "active",
135
+ limit: int = 20,
136
+ offset: int = 0,
137
+ category: Optional[str] = None
138
+ ) -> List[Dict]:
139
+ """Get magazines with filtering
140
+
141
+ Args:
142
+ status: Filter by status (active, archived)
143
+ limit: Maximum number of results
144
+ offset: Offset for pagination
145
+ category: Filter by category
146
+
147
+ Returns:
148
+ List of magazine dictionaries
149
+ """
150
+ response = await self._send_request('familio_get_magazines', {
151
+ 'limit': limit,
152
+ 'offset': offset
153
+ })
154
+
155
+ if response and response.get('type') == 'familio_magazines':
156
+ magazines = response.get('magazines', [])
157
+
158
+ if category:
159
+ magazines = [m for m in magazines if m.get('category') == category]
160
+
161
+ return magazines
162
+
163
+ return []
164
+
165
+ async def get_magazine(self, magazine_id: int) -> Optional[Dict]:
166
+ """Get a single magazine by ID
167
+
168
+ Args:
169
+ magazine_id: Magazine ID
170
+
171
+ Returns:
172
+ Magazine dictionary or None
173
+ """
174
+ magazines = await self.get_magazines()
175
+
176
+ for magazine in magazines:
177
+ if magazine.get('id') == magazine_id:
178
+ return magazine
179
+
180
+ return None
181
+
182
+ async def close(self):
183
+ """Close WebSocket connection"""
184
+ if self.websocket:
185
+ await self.websocket.close()
186
+ self.websocket = None
187
+
188
+
189
+ def create_websocket_familio_client(websocket_url: str, ai_id: int, ai_name: str, ai_nickname: Optional[str] = None) -> WebSocketFamilioClient:
190
+ """Create a WebSocket familio client
191
+
192
+ Args:
193
+ websocket_url: WebSocket server URL
194
+ ai_id: AI ID from CloudBrain
195
+ ai_name: AI full name
196
+ ai_nickname: AI nickname
197
+
198
+ Returns:
199
+ WebSocketFamilioClient instance
200
+ """
201
+ return WebSocketFamilioClient(websocket_url, ai_id, ai_name, ai_nickname)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudbrain-modules
3
- Version: 1.0.6
3
+ Version: 1.0.7
4
4
  Summary: CloudBrain Modules - AI blog, community, and bug tracking features
5
5
  Author: CloudBrain Team
6
6
  License: MIT
@@ -17,4 +17,5 @@ cloudbrain_modules/ai_blog/websocket_blog_client.py
17
17
  cloudbrain_modules/ai_familio/__init__.py
18
18
  cloudbrain_modules/ai_familio/familio_api.py
19
19
  cloudbrain_modules/ai_familio/init_familio_db.py
20
+ cloudbrain_modules/ai_familio/websocket_familio_client.py
20
21
  cloudbrain_modules/bug_tracker/__init__.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "cloudbrain-modules"
7
- version = "1.0.6"
7
+ version = "1.0.7"
8
8
  description = "CloudBrain Modules - AI blog, community, and bug tracking features"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"