complete easy endpoints
This commit is contained in:
parent
58c8708467
commit
8bff435ef3
@ -5,3 +5,4 @@ Flask-RESTful
|
|||||||
marshmallow
|
marshmallow
|
||||||
flask-marshmallow
|
flask-marshmallow
|
||||||
flask-redis
|
flask-redis
|
||||||
|
py-healthcheck
|
||||||
|
16
src/app.py
16
src/app.py
@ -2,12 +2,16 @@
|
|||||||
from flask import Flask
|
from flask import Flask
|
||||||
from flask_restful import Api
|
from flask_restful import Api
|
||||||
import sentry_sdk
|
import sentry_sdk
|
||||||
|
from healthcheck import HealthCheck
|
||||||
from sentry_sdk.integrations.flask import FlaskIntegration
|
from sentry_sdk.integrations.flask import FlaskIntegration
|
||||||
|
|
||||||
from redis_client import redis_client
|
from redis_client import redis_client
|
||||||
from config import Config
|
from config import Config
|
||||||
from marshm import ma
|
from marshm import ma
|
||||||
from resources import SampleResource
|
from errorhandlers import register_all_error_handlers
|
||||||
|
from healthchecks import redis_available
|
||||||
|
from resources import ServiceDiscoveryResource, ServiceLocationResource, ServiceDatabaseResource, \
|
||||||
|
ServiceDatabaseItemResource
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Main Flask RESTful API
|
Main Flask RESTful API
|
||||||
@ -33,12 +37,18 @@ app.config.from_object(Config)
|
|||||||
|
|
||||||
api = Api(app)
|
api = Api(app)
|
||||||
ma.init_app(app)
|
ma.init_app(app)
|
||||||
|
health = HealthCheck()
|
||||||
redis_client.init_app(app)
|
redis_client.init_app(app)
|
||||||
|
|
||||||
|
api.add_resource(ServiceDiscoveryResource, "/service/directory")
|
||||||
|
api.add_resource(ServiceLocationResource, "/service/location/<serviceid>")
|
||||||
|
api.add_resource(ServiceDatabaseResource, "/service")
|
||||||
|
api.add_resource(ServiceDatabaseItemResource, "/service/<serviceid>")
|
||||||
|
|
||||||
api.add_resource(SampleResource, "/input")
|
health.add_check(redis_available)
|
||||||
|
app.add_url_rule("/healthz", "healthcheck", view_func=lambda: health.run())
|
||||||
|
|
||||||
|
register_all_error_handlers(app)
|
||||||
|
|
||||||
if __name__ != '__main__':
|
if __name__ != '__main__':
|
||||||
import logging
|
import logging
|
||||||
|
@ -19,4 +19,4 @@ class Config:
|
|||||||
RELEASE_ID = os.environ.get("RELEASE_ID", "test")
|
RELEASE_ID = os.environ.get("RELEASE_ID", "test")
|
||||||
RELEASEMODE = os.environ.get("RELEASEMODE", "dev")
|
RELEASEMODE = os.environ.get("RELEASEMODE", "dev")
|
||||||
|
|
||||||
REDIS_URL = os.environ['CACHE_REDIS_URL']
|
REDIS_URL = os.environ['REDIS_URL']
|
||||||
|
27
src/errorhandlers.py
Normal file
27
src/errorhandlers.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
"""
|
||||||
|
Flask error handler functions
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = '@tormakris'
|
||||||
|
__copyright__ = "Copyright 2021, KMLabz Team"
|
||||||
|
__module_name__ = "errorhandlers"
|
||||||
|
__version__text__ = "1"
|
||||||
|
|
||||||
|
|
||||||
|
def get_standard_error_handler(code: int):
|
||||||
|
def error_handler(err):
|
||||||
|
return {"msg": str(err)}, code
|
||||||
|
|
||||||
|
return error_handler
|
||||||
|
|
||||||
|
|
||||||
|
# function to register all handlers
|
||||||
|
|
||||||
|
|
||||||
|
def register_all_error_handlers(app):
|
||||||
|
error_codes_to_override = [404, 403, 401, 405, 400, 409, 422]
|
||||||
|
|
||||||
|
for code in error_codes_to_override:
|
||||||
|
app.register_error_handler(code, get_standard_error_handler(code))
|
17
src/healthchecks.py
Normal file
17
src/healthchecks.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from redis_client import redis_client
|
||||||
|
|
||||||
|
"""
|
||||||
|
Healthchek functions
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = "@tormakris"
|
||||||
|
__copyright__ = "Copyright 2021, KMLabz Team"
|
||||||
|
__module_name__ = "healthchecks"
|
||||||
|
__version__text__ = "1"
|
||||||
|
|
||||||
|
|
||||||
|
def redis_available():
|
||||||
|
redisstatus = redis_client.info()
|
||||||
|
return True, redisstatus
|
112
src/resources.py
112
src/resources.py
@ -0,0 +1,112 @@
|
|||||||
|
"""
|
||||||
|
Endpoinds to serve location API
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = '@tormakris'
|
||||||
|
__copyright__ = "Copyright 2021, KMLabz Team"
|
||||||
|
__module_name__ = "resources"
|
||||||
|
__version__text__ = "1"
|
||||||
|
|
||||||
|
import json
|
||||||
|
import random
|
||||||
|
|
||||||
|
from flask import request, current_app, abort
|
||||||
|
from flask_restful import Resource
|
||||||
|
|
||||||
|
from redis_client import redis_client
|
||||||
|
from schemas import ServiceLocatorSchema, ServiceDirectorySchema
|
||||||
|
|
||||||
|
|
||||||
|
class ServiceDiscoveryResource(Resource):
|
||||||
|
"""
|
||||||
|
Service Discovery endpoint
|
||||||
|
"""
|
||||||
|
servicedirectoryschema = ServiceDirectorySchema(many=True)
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
try:
|
||||||
|
servicelist = self.servicedirectoryschema.load(json.load(redis_client.get('servicelist').decode('UTF-8')))
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(e)
|
||||||
|
abort(404, "not found")
|
||||||
|
return self.servicedirectoryschema.dump(servicelist), 200
|
||||||
|
|
||||||
|
|
||||||
|
class ServiceLocationResource(Resource):
|
||||||
|
"""
|
||||||
|
Service location endpoint
|
||||||
|
"""
|
||||||
|
servicelocatorschema = ServiceLocatorSchema(many=False)
|
||||||
|
|
||||||
|
def get(self, serviceid: str):
|
||||||
|
try:
|
||||||
|
serviceobject: dict = self.servicelocatorschema.load(json.load(redis_client.get(serviceid).decode('UTF-8')))
|
||||||
|
servicelocation: str = random.choice(serviceobject['servicearray'])['location']
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(e)
|
||||||
|
abort(404, "not found")
|
||||||
|
return {"location": servicelocation}, 200
|
||||||
|
|
||||||
|
|
||||||
|
class ServiceDatabaseResource(Resource):
|
||||||
|
"""
|
||||||
|
Service database endpoint
|
||||||
|
"""
|
||||||
|
servicelocatorschema = ServiceLocatorSchema(many=False)
|
||||||
|
servicedirectoryschema = ServiceDirectorySchema(many=True)
|
||||||
|
|
||||||
|
def post(self):
|
||||||
|
try:
|
||||||
|
body = request.get_json()
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(e)
|
||||||
|
abort(400, "JSON parse error")
|
||||||
|
try:
|
||||||
|
servicelocation = self.servicelocatorschema.load(body)
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(e)
|
||||||
|
abort(417, "invalid JSON schema")
|
||||||
|
try:
|
||||||
|
redis_client.set(servicelocation['id'], self.servicelocatorschema.dump(servicelocation).encode('UTF-8'))
|
||||||
|
servicelist = self.servicedirectoryschema.load(json.load(redis_client.get('servicelist').decode('UTF-8')))
|
||||||
|
servicelist.append({"name": servicelocation['name'], "id": servicelocation['id']})
|
||||||
|
redis_client.set('servicelist', self.servicedirectoryschema.dump(servicelist).encode('UTF-8'))
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(e)
|
||||||
|
abort(404, "not found")
|
||||||
|
return 200
|
||||||
|
|
||||||
|
|
||||||
|
class ServiceDatabaseItemResource(Resource):
|
||||||
|
"""
|
||||||
|
Service database endpoint interacting with individual items
|
||||||
|
"""
|
||||||
|
servicelocatorschema = ServiceLocatorSchema(many=False)
|
||||||
|
servicedirectoryschema = ServiceDirectorySchema(many=True)
|
||||||
|
|
||||||
|
def put(self, serviceid: str):
|
||||||
|
try:
|
||||||
|
body = request.get_json()
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(e)
|
||||||
|
abort(400, "JSON parse error")
|
||||||
|
try:
|
||||||
|
servicelocation = self.servicelocatorschema.load(body)
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(e)
|
||||||
|
abort(417, "invalid JSON schema")
|
||||||
|
try:
|
||||||
|
redis_client.get(serviceid)
|
||||||
|
redis_client.set(serviceid, self.servicelocatorschema.dump(servicelocation).encode('UTF-8'))
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(e)
|
||||||
|
abort(404, "not found")
|
||||||
|
return 200
|
||||||
|
|
||||||
|
def get(self, serviceid: str):
|
||||||
|
try:
|
||||||
|
servicelocation = self.servicelocatorschema.load(json.load(redis_client.get(serviceid).decode('UTF-8')))
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(e)
|
||||||
|
abort(404, "not found")
|
||||||
|
return servicelocation, 200
|
Loading…
Reference in New Issue
Block a user