Skip to content
This repository has been archived by the owner on Nov 14, 2023. It is now read-only.

Commit

Permalink
Add simple health check endpoint to check API accessibility:
Browse files Browse the repository at this point in the history
- Add API monitoring config variables; API URL and access token
- Monitor authentication, raw data and mapathon endpoints
- Add system health validation models
  • Loading branch information
d-rita committed Sep 26, 2022
1 parent b653461 commit e69ce11
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 2 deletions.
2 changes: 2 additions & 0 deletions API/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
from .download_export import router as download_router
# from .test_router import router as test_router
from .status import router as status_router
from .system import router as health_router
from src.galaxy.db_session import database_instance
from src.galaxy.config import use_connection_pooling, use_s3_to_upload, logger as logging, config
from fastapi_versioning import VersionedFastAPI
Expand Down Expand Up @@ -71,6 +72,7 @@
app.include_router(tm_router)
app.include_router(status_router)
app.include_router(raw_data_router)
app.include_router(health_router)

if use_s3_to_upload is False:
# only mount the disk if config is set to disk
Expand Down
50 changes: 50 additions & 0 deletions API/system.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Copyright (C) 2021 Humanitarian OpenStreetmap Team

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

# Humanitarian OpenStreetmap Team
# 1100 13th Street NW Suite 800 Washington, D.C. 20005
# <[email protected]>

"""
Router Responsible for Checking API Health
"""

from fastapi import APIRouter
from fastapi_versioning import version
from src.galaxy.config import MAIN_API_URL
from src.galaxy.validation.models import SystemHealthOutput, SystemHealthType
from src.galaxy.app import SystemHealth
from .test_data import raw_data_testing_query, mapathon_testing_query

router = APIRouter(prefix="/health")

@router.get("/", response_model=SystemHealthOutput)
@version(1)
def check_system_health():
"""Simple health check for API accessibility"""

authentication = SystemHealth().monitor_endpoint(endpoint=f'{MAIN_API_URL}/auth/login/', request_type='GET')
mapathon_summary = SystemHealth().monitor_endpoint(endpoint=f'{MAIN_API_URL}/mapathon/summary/', request_type='POST', body=mapathon_testing_query)
mapathon_detail = SystemHealth().monitor_endpoint(endpoint=f'{MAIN_API_URL}/mapathon/detail/', request_type='POST', body=mapathon_testing_query)
raw_data = SystemHealth().monitor_endpoint(endpoint=f'{MAIN_API_URL}/raw-data/current-snapshot/', request_type='POST', body=raw_data_testing_query)

return {
"authentication" : SystemHealthType.HEALTHY.value if authentication == 200 else SystemHealthType.UNHEALTHY.value,
"mapathon_summary" : SystemHealthType.HEALTHY.value if mapathon_summary == 200 else SystemHealthType.UNHEALTHY.value,
"mapathon_detail" : SystemHealthType.HEALTHY.value if mapathon_detail == 200 else SystemHealthType.UNHEALTHY.value,
"raw_data" : SystemHealthType.HEALTHY.value if raw_data == 200 else SystemHealthType.UNHEALTHY.value
}


36 changes: 36 additions & 0 deletions API/test_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
raw_data_testing_query = {
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
83.96919250488281,
28.194446860487773
],
[
83.99751663208006,
28.194446860487773
],
[
83.99751663208006,
28.214869548073377
],
[
83.96919250488281,
28.214869548073377
],
[
83.96919250488281,
28.194446860487773
]
]
]
}
}

mapathon_testing_query = {
"fromTimestamp":"2022-07-22T13:15:00.461",
"toTimestamp":"2022-07-22T14:15:00.461",
"projectIds":[],
"hashtags":[ "missingmaps" ]
}
6 changes: 5 additions & 1 deletion src/config.txt.sample
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ secret_key=PutSomethingRandmHere
env=dev

#############
# OPTIONNAL #
# OPTIONAL #
#############

# If enable this [API_CONFIG] section, remove the previous one
Expand All @@ -49,6 +49,10 @@ env=dev
#env=dev # default is prod , supported values are dev and prod
#shp_limit=6000 # in mb default is 4096

#[API_MONITORING]
#MAIN_API_URL=http://127.0.0.1:8000/v1/
#ACCESS_TOKEN=''

#[EXPORT_UPLOAD]
#FILE_UPLOAD_METHOD=disk # options are s3,disk
#AWS_ACCESS_KEY_ID= your id
Expand Down
14 changes: 13 additions & 1 deletion src/galaxy/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
import os
import sys
import threading
from .config import get_db_connection_params, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, BUCKET_NAME, level, logger as logging, export_path, use_connection_pooling, shp_limit
import requests
from .config import get_db_connection_params, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, BUCKET_NAME, level, logger as logging, export_path, use_connection_pooling, shp_limit, ACCESS_TOKEN
from .validation.models import Source
from psycopg2 import connect, sql
from psycopg2.extras import DictCursor
Expand Down Expand Up @@ -1324,3 +1325,14 @@ def __call__(self, bytes_amount):
percentage = (self._seen_so_far / self._size) * 100
logging.debug("\r%s %s / %s (%.2f%%)", self._filename,
self._seen_so_far, self._size, percentage)


class SystemHealth(object):
@staticmethod
def monitor_endpoint(endpoint, request_type, body=None):
if request_type == 'GET':
get_req = requests.get(endpoint)
return get_req.status_code
if request_type == 'POST':
post_req = requests.post(endpoint, json=body, headers={'access-token':ACCESS_TOKEN})
return post_req.status_code
3 changes: 3 additions & 0 deletions src/galaxy/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@
"value not supported for file_upload_method ,switching to default disk method")
use_s3_to_upload = False

MAIN_API_URL = config.get("API_MONITORING", "MAIN_API_URL", fallback="http://127.0.0.1:8000/v1/")
ACCESS_TOKEN = config.get("API_MONITORING", "ACCESS_TOKEN", fallback=None)


def get_db_connection_params(dbIdentifier: str) -> dict:
"""Return a python dict that can be passed to psycopg2 connections
Expand Down
10 changes: 10 additions & 0 deletions src/galaxy/validation/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -678,3 +678,13 @@ class DataOutput(str, Enum):
class DataRecencyParams(BaseModel):
data_source: DataSource
data_output: DataOutput

class SystemHealthType(Enum):
HEALTHY = "healthy"
UNHEALTHY = "unhealthy"

class SystemHealthOutput(BaseModel):
authentication: SystemHealthType
mapathon_summary: SystemHealthType
mapathon_detail: SystemHealthType
raw_data: SystemHealthType

0 comments on commit e69ce11

Please sign in to comment.