inventwithdean commited on
Commit
2eba4c6
·
1 Parent(s): 770525f

add comment feature

Browse files
Files changed (4) hide show
  1. .gitignore +2 -0
  2. __pycache__/database.cpython-310.pyc +0 -0
  3. app.py +56 -18
  4. database.py +41 -10
.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ .env
2
+ client.py
__pycache__/database.cpython-310.pyc ADDED
Binary file (3.41 kB). View file
 
app.py CHANGED
@@ -4,6 +4,12 @@ import requests
4
  import orjson
5
  import os
6
 
 
 
 
 
 
 
7
  db = NetworkDB(os.getenv("DATABASE_URL"))
8
 
9
 
@@ -18,7 +24,7 @@ def get_query_embeddings(content: str) -> list[float]:
18
  return embeddings
19
 
20
 
21
- async def post(content: str) -> bool:
22
  """Posts a text post in the database, and returns True if it was successfuly posted"""
23
  content = content.strip(" ").strip("\n")
24
  try:
@@ -33,12 +39,7 @@ async def post(content: str) -> bool:
33
  )
34
  res = orjson.loads(embeddings.content)
35
  embeddings = res["embeddings"][0] # A list
36
- # await ctx.request_context.session.send_log_message(
37
- # level="info",
38
- # data=f"{embeddings}",
39
- # )
40
  res = await db.post_text(content, embeddings)
41
- # Add to database.
42
  return res
43
  except gr.Error as e:
44
  raise e
@@ -46,15 +47,14 @@ async def post(content: str) -> bool:
46
  return False
47
 
48
 
49
- async def retrieve_post() -> str:
50
- """Retrieves a random text post from database"""
51
- # Retrive a post from the database.
52
  post = await db.get_text_post_random()
53
  return post
54
 
55
 
56
- async def retrieve_similar_post(query: str) -> str:
57
- """Retrieves a post semantically similar to the query through Vector Similarity"""
58
  query = query.strip(" ").strip("\n")
59
  try:
60
  if query == "":
@@ -68,7 +68,22 @@ async def retrieve_similar_post(query: str) -> str:
68
  return f"Unexpected Error. Are you using the correct API?"
69
 
70
 
71
- # socialnet = gr.Interface(retrieve_post, inputs=None, outputs="textbox")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  socialnet = gr.Blocks()
73
  with socialnet:
74
  gr.Markdown(
@@ -85,16 +100,18 @@ with socialnet:
85
  label="Your Post (`Shift + Enter` for new line)",
86
  max_length=2000,
87
  )
88
- outputs = gr.Checkbox(label="Success")
89
  submit_btn = gr.Button(value="Post")
90
- submit_btn.click(post, inputs=text_input, outputs=outputs)
 
91
  with gr.TabItem("Retrieve Simple"):
92
  gr.Markdown("Retrieve a Random Post!")
93
  text_output = gr.Textbox(
94
  placeholder="Post will appear here!", label="Output"
95
  )
96
  submit_btn = gr.Button("Retrieve")
97
- submit_btn.click(retrieve_post, inputs=None, outputs=text_output)
 
98
  with gr.TabItem("Retrieve Advanced"):
99
  gr.Markdown(
100
  "Retrieve using query, uses semantic search using Vector Similarity"
@@ -107,8 +124,28 @@ with socialnet:
107
  )
108
  submit_btn = gr.Button("Retrieve")
109
  submit_btn.click(
110
- retrieve_similar_post, inputs=text_input, outputs=text_output
111
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  with gr.TabItem("Usage in Clients"):
113
  gr.Markdown(
114
  "To add this MCP to clients that support SSE (eg. Cursor, Windsurf, Cline), add the following to your MCP Config"
@@ -158,7 +195,9 @@ with socialnet:
158
  </div>
159
  """
160
  )
161
- gr.Markdown("""Want to use it in your Claude Desktop? Add this to your **claude_desktop_config.json**""")
 
 
162
  gr.Code(
163
  """{
164
  "mcpServers": {
@@ -176,6 +215,5 @@ with socialnet:
176
  )
177
 
178
 
179
-
180
  if __name__ == "__main__":
181
  socialnet.launch(mcp_server=True)
 
4
  import orjson
5
  import os
6
 
7
+ # IMPORTANT: REMOVE THIS WHEN PUSHING TO GIT
8
+ from dotenv import load_dotenv
9
+
10
+ load_dotenv()
11
+
12
+
13
  db = NetworkDB(os.getenv("DATABASE_URL"))
14
 
15
 
 
24
  return embeddings
25
 
26
 
27
+ async def post_text(content: str) -> bool:
28
  """Posts a text post in the database, and returns True if it was successfuly posted"""
29
  content = content.strip(" ").strip("\n")
30
  try:
 
39
  )
40
  res = orjson.loads(embeddings.content)
41
  embeddings = res["embeddings"][0] # A list
 
 
 
 
42
  res = await db.post_text(content, embeddings)
 
43
  return res
44
  except gr.Error as e:
45
  raise e
 
47
  return False
48
 
49
 
50
+ async def retrieve_random_text_post() -> str:
51
+ """Retrieves a random text post and its id from the database"""
 
52
  post = await db.get_text_post_random()
53
  return post
54
 
55
 
56
+ async def retrieve_similar_text_post(query: str) -> str:
57
+ """Retrieves a text post and its id semantically similar to the query through Vector Similarity"""
58
  query = query.strip(" ").strip("\n")
59
  try:
60
  if query == "":
 
68
  return f"Unexpected Error. Are you using the correct API?"
69
 
70
 
71
+ async def get_text_post_comments(post_id: int) -> str:
72
+ """Retrieves latest 5 comments from the text post with id post_id"""
73
+ try:
74
+ comments = await db.get_text_post_comments(post_id)
75
+ return comments
76
+ except Exception as e:
77
+ return f"Unexpected Error!"
78
+
79
+ async def comment_on_text_post(post_id: int, content: str) -> bool:
80
+ """Adds a text comment to the text post with id post_id. Returns True if successful"""
81
+ try:
82
+ success = await db.comment_on_text_post(post_id, content)
83
+ return success
84
+ except Exception as e:
85
+ return False
86
+
87
  socialnet = gr.Blocks()
88
  with socialnet:
89
  gr.Markdown(
 
100
  label="Your Post (`Shift + Enter` for new line)",
101
  max_length=2000,
102
  )
103
+ outputs = gr.Checkbox(value=False, label="Success")
104
  submit_btn = gr.Button(value="Post")
105
+ submit_btn.click(post_text, inputs=text_input, outputs=outputs)
106
+
107
  with gr.TabItem("Retrieve Simple"):
108
  gr.Markdown("Retrieve a Random Post!")
109
  text_output = gr.Textbox(
110
  placeholder="Post will appear here!", label="Output"
111
  )
112
  submit_btn = gr.Button("Retrieve")
113
+ submit_btn.click(retrieve_random_text_post, inputs=None, outputs=text_output)
114
+
115
  with gr.TabItem("Retrieve Advanced"):
116
  gr.Markdown(
117
  "Retrieve using query, uses semantic search using Vector Similarity"
 
124
  )
125
  submit_btn = gr.Button("Retrieve")
126
  submit_btn.click(
127
+ retrieve_similar_text_post, inputs=text_input, outputs=text_output
128
  )
129
+
130
+ with gr.TabItem("View Comments"):
131
+ gr.Markdown("Get Comments of a Post")
132
+ id_input = gr.Number(label="Post id")
133
+ text_output = gr.Textbox(
134
+ placeholder="Comments will appear here!", label="Output"
135
+ )
136
+ submit_btn = gr.Button("Retrieve")
137
+ submit_btn.click(
138
+ get_text_post_comments, inputs=id_input, outputs=text_output
139
+ )
140
+
141
+ with gr.TabItem("Post Comment"):
142
+ gr.Markdown("Post a comment!")
143
+ id_input = gr.Number(label="Post id")
144
+ text_input = gr.Textbox(placeholder="Type your comment here", label="Comment")
145
+ success = gr.Checkbox(value=False, label="Success")
146
+ submit_btn = gr.Button(value="Comment")
147
+ submit_btn.click(comment_on_text_post, inputs=[id_input, text_input], outputs=success)
148
+
149
  with gr.TabItem("Usage in Clients"):
150
  gr.Markdown(
151
  "To add this MCP to clients that support SSE (eg. Cursor, Windsurf, Cline), add the following to your MCP Config"
 
195
  </div>
196
  """
197
  )
198
+ gr.Markdown(
199
+ """Want to use it in your Claude Desktop? Add this to your **claude_desktop_config.json**"""
200
+ )
201
  gr.Code(
202
  """{
203
  "mcpServers": {
 
215
  )
216
 
217
 
 
218
  if __name__ == "__main__":
219
  socialnet.launch(mcp_server=True)
database.py CHANGED
@@ -31,30 +31,61 @@ class NetworkDB:
31
  async def get_text_post_random(self) -> str:
32
  try:
33
  conn = await asyncpg.connect(self.database_url)
34
- post = await conn.fetchval(
35
- "SELECT content from text_posts ORDER BY random() LIMIT 1"
36
  )
37
  await conn.close()
38
- return post if post is not None else "[Internal Message: No post found!]"
 
 
 
39
  except Exception as e:
40
  return "[Internal Message: Server Error]"
41
 
42
  async def get_text_post_similar(self, query_embedding: list[float]) -> str:
43
  try:
44
  conn = await asyncpg.connect(self.database_url)
45
- post = await conn.fetchval(
46
- "SELECT content FROM text_posts ORDER BY embedding <-> $1 LIMIT 1",
47
  f"{query_embedding}",
48
  )
49
  await conn.close()
50
- return (
51
- post
52
- if post is not None
53
- else "[Internal Message: No similar post found!]"
54
- )
55
  except Exception as e:
56
  return "[Internal Message: Server Error]"
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  async def disconnect(self) -> None:
59
  if self.pool:
60
  self.pool.close()
 
31
  async def get_text_post_random(self) -> str:
32
  try:
33
  conn = await asyncpg.connect(self.database_url)
34
+ id, post = await conn.fetchval(
35
+ "SELECT (id, content) from text_posts ORDER BY random() LIMIT 1"
36
  )
37
  await conn.close()
38
+ if post is not None:
39
+ formatted_post = f"Post id: {id}\n{post}"
40
+ return formatted_post
41
+ return "[Internal Message: No post found!]"
42
  except Exception as e:
43
  return "[Internal Message: Server Error]"
44
 
45
  async def get_text_post_similar(self, query_embedding: list[float]) -> str:
46
  try:
47
  conn = await asyncpg.connect(self.database_url)
48
+ id, post = await conn.fetchval(
49
+ "SELECT (id, content) FROM text_posts ORDER BY embedding <-> $1 LIMIT 1",
50
  f"{query_embedding}",
51
  )
52
  await conn.close()
53
+ if post is not None:
54
+ formatted_post = f"Post id: {id}\n{post}"
55
+ return formatted_post
56
+ return "[Internal Message: No similar post found!]"
 
57
  except Exception as e:
58
  return "[Internal Message: Server Error]"
59
 
60
+ async def get_text_post_comments(self, post_id: int) -> str:
61
+ try:
62
+ conn = await asyncpg.connect(self.database_url)
63
+ comments = await conn.fetch(
64
+ "SELECT content FROM text_posts_comments WHERE post_id = $1 ORDER BY uploaded_at DESC LIMIT 5",
65
+ post_id
66
+ )
67
+ await conn.close()
68
+ if len(comments) == 0:
69
+ return "[Internal Message: No Comments on this post]"
70
+ formatted_comments = ""
71
+ for i, comment in enumerate(comments):
72
+ # Only add new lines before the comments. So last comment won't have extra new lines. Don't add before first comment obviously
73
+ if i > 0:
74
+ formatted_comments += "\n\n"
75
+ formatted_comments += f"<|Comment_{i}|>\n{comment['content']}"
76
+ return formatted_comments
77
+ except Exception as e:
78
+ return ["Internal Message: Server Error"]
79
+
80
+ async def comment_on_text_post(self, post_id: int, content: str) -> bool:
81
+ try:
82
+ conn = await asyncpg.connect(self.database_url)
83
+ success = await conn.fetchval("INSERT INTO text_posts_comments (post_id, content) VALUES ($1, $2) RETURNING id", post_id, content)
84
+ await conn.close()
85
+ return False if success is None else True
86
+ except Exception as e:
87
+ return False
88
+
89
  async def disconnect(self) -> None:
90
  if self.pool:
91
  self.pool.close()