-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
141 lines (119 loc) · 4.13 KB
/
app.py
File metadata and controls
141 lines (119 loc) · 4.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
from fastapi_mcp import FastApiMCP
from fastapi import FastAPI, HTTPException
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse, RedirectResponse
from pydantic import BaseModel
from dotenv import load_dotenv
import os
import psycopg2
import redis
import uvicorn
# Load environment variables
load_dotenv()
PASS = os.getenv('PASS')
USER = os.getenv('USER')
DATABASE = os.getenv('DATABASE')
HOST = os.getenv('HOST')
# Redis
redis_client = redis.StrictRedis(host='localhost', port=6379, db=0)
# FastAPI and mcp mounting
app = FastAPI()
#icon
@app.get('/favicon.ico', include_in_schema=False)
async def favicon():
return FileResponse(os.path.join(os.path.dirname(__file__), 'icon.ico'))
class NoCacheStaticFiles(StaticFiles):
async def get_response(self, path, scope):
response = await super().get_response(path, scope)
response.headers["Cache-Control"] = "no-store"
return response
# Serve static files with no caching
app.mount("/static", NoCacheStaticFiles(directory="static"), name="static")
# Database connection function
def get_connection():
try:
return psycopg2.connect(
database=DATABASE,
user=USER,
password=PASS,
host=HOST,
port=5432,
)
except Exception as e:
print("Error connecting to the database:", e)
return None
# Pydantic model for notes
class Note(BaseModel):
id: int
title: str
content: str
@app.get('/')
async def root():
return RedirectResponse(url="http://127.0.0.1:8000/static/index.html")
# Add necessary attributes to MCP-integrated routes
@app.get("/notes", operation_id="view_all_notes", tags=["MCP"])
async def view_notes():
cached_notes = redis_client.get("notes")
if cached_notes:
print(eval(cached_notes))
return {"notes": eval(cached_notes)}
conn = get_connection()
if not conn:
raise HTTPException(status_code=500, detail="Database connection failed")
curr = conn.cursor()
curr.execute("SELECT * FROM notetaker;")
notes = curr.fetchall()
conn.close()
print("Here is notes:\n",notes)
redis_client.set("notes", str(notes))
return {"notes": notes}
@app.post("/notes", operation_id="create_note", tags=["MCP"])
async def create_note(note: Note):
conn = get_connection()
if not conn:
raise HTTPException(status_code=500, detail="Database connection failed")
curr = conn.cursor()
curr.execute(
"INSERT INTO notetaker (title, content) VALUES (%s, %s);",
(note.title, note.content),
)
conn.commit()
conn.close()
redis_client.delete("notes") # clear cache
return {"message": "Note created successfully"}
@app.delete("/notes/{note_id}", operation_id="delete_note_given_id", tags=["MCP"])
async def delete_note(note_id: int):
conn = get_connection()
if not conn:
raise HTTPException(status_code=500, detail="Database connection failed")
curr = conn.cursor()
curr.execute("DELETE FROM notetaker WHERE id = %s;", (note_id,))
conn.commit()
conn.close()
redis_client.delete("notes") # clear cache
return {"message": "Note deleted successfully"}
@app.put("/notes/{note_id}", operation_id="update_note_title_or_content", tags=["MCP"])
async def update_note(note_id: int, note: Note):
"""Update a note by ID."""
conn = get_connection()
if not conn:
raise HTTPException(status_code=500, detail="Database connection failed")
curr = conn.cursor()
curr.execute(
"UPDATE notetaker SET title = %s, content = %s WHERE id = %s;",
(note.title, note.content, note_id),
)
conn.commit()
conn.close()
redis_client.delete("notes") # clear cache
return {"message": "Note updated successfully"}
# Mount MCP server after all routes are declared
mcp = FastApiMCP(
app,
name="My Notetaking app's server",
description="This is an endpoint for mcp server",
include_operations=["view_all_notes", "create_note", "delete_note_given_id", "update_note_title_or_content"]
)
mcp.mount()
if __name__ == '__main__':
uvicorn.run("app:app", host="127.0.0.1", port=8000, reload=True)