Skip to content

Commit aeabd74

Browse files
committed
maintenance + assign tag to monitor + redirect slashes
1 parent e65579f commit aeabd74

21 files changed

+285
-33
lines changed

app/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class Settings(BaseSettings):
1010
PROJECT_NAME: str="Uptime-Kuma-API"
1111
BACKEND_CORS_ORIGINS: List[AnyHttpUrl] = []
1212

13-
ACCESS_TOKEN_EXPIRE: int = 60 * 24 * 8 #8 days
13+
ACCESS_TOKEN_EXPIRE: int = os.environ.get('ACCESS_TOKEN_EXPIRATION',60 * 24 * 8) #8 days
1414
SECRET_KEY: str = secrets.token_urlsafe(32)
1515

1616
KUMA_SERVER: str = os.environ.get('KUMA_SERVER')

app/main.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,21 @@
22
from fastapi.responses import RedirectResponse
33
import os
44

5-
from routers import monitor, auth, tags, cert, info, uptime, ping, database, settings as settings, user
5+
from routers import monitor, auth, tags, cert, info, uptime, ping, database, settings as settings, user, maintenance
66
from config import settings as app_settings
77
from utils.admin import check_admin
88

9-
from tortoise.contrib.fastapi import register_tortoise
109
from tortoise import Tortoise
1110

1211

1312
app = FastAPI(title=app_settings.PROJECT_NAME)
14-
15-
13+
app.router.redirect_slashes = True
1614

1715
app.include_router(user.router, prefix="/users", tags=["Users"])
1816
app.include_router(settings.router, prefix="/settings", tags=["Settings"])
1917
app.include_router(database.router, prefix="/database", tags=["DataBase"])
2018
app.include_router(monitor.router, prefix="/monitors", tags=["Monitor"])
19+
app.include_router(maintenance.router, prefix="/maintenance", tags=["Maintenance"])
2120
app.include_router(tags.router, prefix="/tags", tags=["Tags"])
2221
app.include_router(cert.router, prefix="/cert_info", tags=["Certification Info"])
2322
app.include_router(info.router, prefix="/info", tags=["Informations"])
@@ -46,6 +45,7 @@ async def startup_event():
4645
async def shutdown_event():
4746
await Tortoise.close_connections()
4847

48+
4949
@app.get("/", include_in_schema=False)
5050
async def root():
5151
return RedirectResponse(url='/docs')

app/routers/auth.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
from config import logger as logging, settings
1414

1515

16-
router = APIRouter()
16+
router = APIRouter(redirect_slashes=True)
1717

1818

19-
@router.post("/access-token/", response_model = JWToken)
19+
@router.post("/access-token", response_model = JWToken)
2020
async def login_access_token(form_data : OAuth2PasswordRequestForm = Depends()):
2121
user_obj = await Users.get_or_none(username=form_data.username)
2222
user = authenticate(user_obj, form_data.password)
@@ -28,7 +28,7 @@ async def login_access_token(form_data : OAuth2PasswordRequestForm = Depends()):
2828
user.last_visit = datetime.now()
2929
await user.save(update_fields=["last_visit"])
3030

31-
logging.fatal(f"hellooooooooooooo {settings.KUMA_SERVER}")
31+
logging.fatal(f"hello from {settings.KUMA_SERVER}")
3232
api = UptimeKumaApi(settings.KUMA_SERVER)
3333
resp = api.login(settings.KUMA_USERNAME, settings.KUMA_PASSWORD)
3434

app/routers/cert.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
from schemas.api import API
66
from utils.deps import get_current_user
77

8-
router = APIRouter()
8+
router = APIRouter(redirect_slashes=True)
99

1010

11-
@router.get("/", description="Get Certification Info")
11+
@router.get("", description="Get Certification Info")
1212
async def get_cert_info(cur_user: API = Depends(get_current_user)):
1313
api : UptimeKumaApi = cur_user['api']
1414
try:

app/routers/database.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from schemas.api import API
66
from utils.deps import get_current_user
77

8-
router = APIRouter()
8+
router = APIRouter(redirect_slashes=True)
99

1010

1111
@router.get("/size", description="Get DataBase Size")

app/routers/info.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
from schemas.api import API
66
from utils.deps import get_current_user
77

8-
router = APIRouter()
8+
router = APIRouter(redirect_slashes=True)
99

1010

11-
@router.get("/", description="Informations")
11+
@router.get("", description="Informations")
1212
async def get_info(cur_user: API = Depends(get_current_user)):
1313
api : UptimeKumaApi = cur_user['api']
1414
try:

app/routers/maintenance.py

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
from fastapi import APIRouter, Depends, HTTPException, Path
2+
from uptime_kuma_api import UptimeKumaApi, UptimeKumaException
3+
from typing import List
4+
5+
from schemas.maintenance import Maintenance, MaintenanceUpdate, MonitorMaintenance
6+
from schemas.api import API
7+
from utils.deps import get_current_user
8+
from config import logger as logging
9+
10+
11+
12+
router = APIRouter(redirect_slashes=True)
13+
14+
@router.get("", description="Get all Maintenances")
15+
async def get_maintenances(cur_user: API = Depends(get_current_user)):
16+
api: UptimeKumaApi = cur_user['api']
17+
try :
18+
return {"maintenances": api.get_maintenances()}
19+
except Exception as e :
20+
logging.fatal(e)
21+
raise HTTPException(500, str(e))
22+
23+
24+
@router.get("/{maintenance_id}", description="Get Maintenance By ID")
25+
async def get_maintenance(maintenance_id:int=Path(...) , cur_user: API = Depends(get_current_user)):
26+
api: UptimeKumaApi = cur_user['api']
27+
28+
if maintenance_id :
29+
try:
30+
maintenance = api.get_maintenance(maintenance_id)
31+
except UptimeKumaException as e:
32+
logging.info(e)
33+
raise HTTPException(404, {"message": "Maintenance not found !"})
34+
except Exception as e :
35+
logging.fatal(e)
36+
raise HTTPException(500, str(e))
37+
38+
return {"maintenance": maintenance }
39+
40+
raise HTTPException(404, {"message": "Maintenance not found !"})
41+
42+
43+
44+
@router.post("", description="Create a Maintenance")
45+
async def create_maintenance(maintenance: Maintenance,cur_user: API = Depends(get_current_user)):
46+
api: UptimeKumaApi = cur_user['api']
47+
try:
48+
resp = api.add_maintenance(**maintenance.dict())
49+
except TypeError as e:
50+
logging.error(e)
51+
raise HTTPException(422, str(e))
52+
except Exception as e :
53+
logging.fatal(e)
54+
raise HTTPException(500, str(e))
55+
56+
return resp
57+
58+
59+
60+
@router.patch("/{maintenance_id}", description="Update a specific Maintenance")
61+
async def update_maintenance(maintenance: MaintenanceUpdate,maintenance_id:int=Path(...) ,cur_user: API = Depends(get_current_user)):
62+
api: UptimeKumaApi = cur_user['api']
63+
try:
64+
resp = api.edit_maintenance(id_=maintenance_id, **maintenance.dict(exclude_unset=True))
65+
except UptimeKumaException as e:
66+
logging.info(e)
67+
raise HTTPException(404, {"message": "Maintenance not found !"})
68+
except TypeError as e:
69+
logging.error(e)
70+
raise HTTPException(422, str(e) )
71+
except Exception as e :
72+
logging.fatal(e)
73+
raise HTTPException(500, str(e))
74+
75+
return {**resp, "maintenance_data":maintenance.dict(exclude_unset=True)}
76+
77+
78+
79+
@router.delete("/{maintenance_id}", description="Delete a specific Maintenance")
80+
async def delete_maintenance(maintenance_id:int=Path(...) ,cur_user: API = Depends(get_current_user)):
81+
api: UptimeKumaApi = cur_user['api']
82+
try:
83+
# kinda dumb the api doesnt check if th id exists he just sends an event
84+
resp = api.delete_maintenance(maintenance_id)
85+
except UptimeKumaException as e:
86+
logging.info(e)
87+
raise HTTPException(404, {"message": "Maintenance not found !"})
88+
except Exception as e :
89+
logging.fatal(e)
90+
raise HTTPException(500, str(e))
91+
92+
return resp
93+
94+
95+
96+
@router.post("/{maintenance_id}/pause", description="Pause a specific maintenance")
97+
async def pause_maintenance(maintenance_id:int=Path(...) ,cur_user: API = Depends(get_current_user)):
98+
api: UptimeKumaApi = cur_user['api']
99+
try:
100+
resp = api.pause_maintenance(maintenance_id)
101+
except UptimeKumaException as e:
102+
logging.info(e)
103+
raise HTTPException(404, {"message": "maintenance not found !"})
104+
except Exception as e :
105+
logging.fatal(e)
106+
raise HTTPException(500, str(e))
107+
108+
return resp
109+
110+
111+
112+
@router.post("/{maintenance_id}/resume", description="Resume a specific maintenance")
113+
async def resume_maintenance(maintenance_id:int=Path(...) ,cur_user: API = Depends(get_current_user)):
114+
api: UptimeKumaApi = cur_user['api']
115+
try:
116+
resp = api.resume_maintenance(maintenance_id)
117+
except UptimeKumaException as e:
118+
logging.info(e)
119+
raise HTTPException(404, {"message": "maintenance not found !"})
120+
except Exception as e :
121+
logging.fatal(e)
122+
raise HTTPException(500, str(e))
123+
124+
return resp
125+
126+
@router.get("/{maintenance_id}/monitors", description="Get monitors to a maintenance.")
127+
async def add_monitor_maintenance(maintenance_id:int=Path(...),cur_user: API = Depends(get_current_user))-> List[MonitorMaintenance]:
128+
api: UptimeKumaApi = cur_user['api']
129+
try:
130+
monitors = api.get_monitor_maintenance(maintenance_id)
131+
except UptimeKumaException as e:
132+
logging.info(e)
133+
raise HTTPException(404, {"message": f"maintenance not found ! "})
134+
except Exception as e :
135+
logging.fatal(e)
136+
raise HTTPException(500, str(e))
137+
138+
return monitors
139+
140+
@router.post("/{maintenance_id}/monitors", description="Adds monitors to a maintenance.")
141+
async def add_monitor_maintenance(monitors: List[MonitorMaintenance], maintenance_id:int=Path(...),cur_user: API = Depends(get_current_user)):
142+
api: UptimeKumaApi = cur_user['api']
143+
try:
144+
mns = [m.dict() for m in monitors]
145+
resp = api.add_monitor_maintenance(maintenance_id, mns)
146+
except UptimeKumaException as e:
147+
logging.info(e)
148+
raise HTTPException(404, {"message": f"maintenance or monitor not found !"})
149+
except Exception as e :
150+
logging.fatal(e)
151+
raise HTTPException(500, str(e))
152+
153+
return resp

app/routers/monitor.py

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
from fastapi import APIRouter, Depends, HTTPException, Path
22
from uptime_kuma_api import UptimeKumaApi, UptimeKumaException
33

4-
from schemas.monitor import Monitor, MonitorUpdate
4+
from schemas.monitor import Monitor, MonitorUpdate, MonitorTag
55
from schemas.api import API
66
from utils.deps import get_current_user
77
from config import logger as logging
88

99

10-
router = APIRouter()
10+
router = APIRouter(redirect_slashes=True)
1111

12-
@router.get("/", description="Get all Monitors")
12+
@router.get("", description="Get all Monitors")
1313
async def get_monitors(cur_user: API = Depends(get_current_user)):
1414
api: UptimeKumaApi = cur_user['api']
1515
try :
@@ -37,7 +37,7 @@ async def get_monitor(monitor_id:int=Path(...) , cur_user: API = Depends(get_cur
3737
raise HTTPException(404, {"message": "Monitor not found !"})
3838

3939

40-
@router.post("/", description="Create a Monitor")
40+
@router.post("", description="Create a Monitor")
4141
async def create_monitor(monitor: Monitor,cur_user: API = Depends(get_current_user)):
4242
api: UptimeKumaApi = cur_user['api']
4343
try:
@@ -136,4 +136,41 @@ async def monitor_beats(monitor_id:int=Path(...), hours:float=1 , cur_user: API
136136

137137

138138
# to be implemented
139-
# api.get_monitor_tags api.edit_monitor_tags api.delete_monitor_tags
139+
# api.get_monitor_tags api.edit_monitor_tags api.delete_monitor_tags
140+
141+
142+
@router.post("/{monitor_id}/tag", description="Add an already created tag to a specific monitor")
143+
async def add_monitor_tag(tag: MonitorTag ,monitor_id:int=Path(...), cur_user: API = Depends(get_current_user)):
144+
api: UptimeKumaApi = cur_user['api']
145+
if monitor_id :
146+
try:
147+
msg = api.add_monitor_tag(monitor_id=monitor_id, **tag.dict())
148+
except UptimeKumaException as e:
149+
logging.info(e)
150+
raise HTTPException(404, {"message": "Monitor or Tag not found !"})
151+
except Exception as e :
152+
logging.fatal(e)
153+
raise HTTPException(500, str(e))
154+
155+
156+
return msg
157+
158+
raise HTTPException(404, {"message": "Monitor not found !"})
159+
160+
@router.delete("/{monitor_id}/tag", description="Delete a tag from a specific monitor")
161+
async def delete_monitor_tag(tag: MonitorTag ,monitor_id:int=Path(...), cur_user: API = Depends(get_current_user)):
162+
api: UptimeKumaApi = cur_user['api']
163+
if monitor_id :
164+
try:
165+
msg = api.delete_monitor_tag(monitor_id=monitor_id, **tag.dict())
166+
except UptimeKumaException as e:
167+
logging.info(e)
168+
raise HTTPException(404, {"message": "Monitor or Tag not found !"})
169+
except Exception as e :
170+
logging.fatal(e)
171+
raise HTTPException(500, str(e))
172+
173+
174+
return msg
175+
176+
raise HTTPException(404, {"message": "Monitor not found !"})

app/routers/ping.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
from schemas.api import API
66
from utils.deps import get_current_user
77

8-
router = APIRouter()
8+
router = APIRouter(redirect_slashes=True)
99

1010

11-
@router.get("/", description="Get AVG Ping")
11+
@router.get("", description="Get AVG Ping")
1212
async def get_avg_ping(cur_user: API = Depends(get_current_user)):
1313
api : UptimeKumaApi = cur_user['api']
1414
try:

app/routers/settings.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
from fastapi import APIRouter, Depends, HTTPException
2-
from fastapi.encoders import jsonable_encoder
32
from uptime_kuma_api import UptimeKumaApi, UptimeKumaException
43

54
from config import logger as logging
65
from schemas.api import API
76
from schemas.settings import Backup, ImportHandleType
87
from utils.deps import get_current_user
98

10-
router = APIRouter()
9+
router = APIRouter(redirect_slashes=True)
1110

1211

1312
@router.post("/upload_backup", description="Upload a Backup")

0 commit comments

Comments
 (0)