{"id":17047453,"url":"https://github.com/djmgit/flask-opsgenie","last_synced_at":"2026-05-06T21:32:53.347Z","repository":{"id":41958430,"uuid":"427090558","full_name":"djmgit/flask-opsgenie","owner":"djmgit","description":"A Flask extension for opsgenie","archived":false,"fork":false,"pushed_at":"2024-03-04T17:06:47.000Z","size":111,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-28T10:24:09.406Z","etag":null,"topics":["alerting","flask","flask-extension","monitoring","opsgenie"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/djmgit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-11T17:42:26.000Z","updated_at":"2021-12-12T13:15:29.000Z","dependencies_parsed_at":"2024-03-04T18:13:02.185Z","dependency_job_id":"0f523bfa-2d3d-43e5-862e-33671d2fc307","html_url":"https://github.com/djmgit/flask-opsgenie","commit_stats":{"total_commits":142,"total_committers":2,"mean_commits":71.0,"dds":0.04929577464788737,"last_synced_commit":"1e7e9b6814de4aaf3ab7c35fe9437e94e89849bc"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djmgit%2Fflask-opsgenie","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djmgit%2Fflask-opsgenie/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djmgit%2Fflask-opsgenie/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djmgit%2Fflask-opsgenie/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/djmgit","download_url":"https://codeload.github.com/djmgit/flask-opsgenie/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245052651,"owners_count":20553163,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alerting","flask","flask-extension","monitoring","opsgenie"],"created_at":"2024-10-14T09:49:31.628Z","updated_at":"2026-05-06T21:32:48.328Z","avatar_url":"https://github.com/djmgit.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":" ![master](https://github.com/djmgit/flask-opsgenie/actions/workflows/run_tests.yml/badge.svg?branch=master)\n\n# Flask Opsgenie\n\nFlask-opsgenie is a flask extension for creating alerts on Opsgenie. Once configured flask-opsgenie can generate an opsgenie alert once a desired condition is met,\nfor example an endpoint returns an unwanted status code (500 may be) or an unwanted status class (5XX or 3XX for some reason) or lets say a given endpoint is\nbreaching response latency threshold or may be it has thrown some exception. Flask-opsgenie will try to send as much details as possible to Opsgenie so that\nthe on-call rockstar can get most of the details looking at the phone screen on receiving the page.\n\n## Getting flask-opsgenie\n\nFlask-opsgenie can be installed using pip. Make sure to have python 3+.\n\n```pip install Flask-Opsgenie```\n\n## Quick Start\n\nLets quickly see how to use flask-opsgenie in an actual flask application.\nFor an easy to get started with example, lets say we want to generate an opsgenie alert whenever a route returns 500 as response status code. Using\nflask-opsgenie we do not need to write our own middleware code to generate the alert.\n\n```\nimport os\nfrom flask import Flask\nfrom flask_opsgenie import FlaskOpsgenie\n\nclass FlaskOpsgenieConfig:\n\n    ALERT_STATUS_CODES = [500]\n    OPSGENIE_TOKEN = os.getenv(\"API_KEY\")\n    ALERT_TAGS = [\"flask_status_alert\"]\n    ALERT_PRIORITY = \"P3\"\n    SERVICE_ID = \"my_flask_service\"\n    RESPONDER = [{\n        \"type\": \"user\",\n        \"username\": \"neo@matrix\"\n    }]\n\napp = Flask(__name__)\napp.config.from_object(FlaskOpsgenieConfig())\nflask_opsgenie = FlaskOpsgenie(None)\nflask_opsgenie.init_app(app)\n\n@app.route(\"/index\", methods=[\"GET\"])\ndef index():\n    return \"Hello world\", 200\n\n@app.route(\"/res500\", methods=[\"GET\"])\ndef res_500():\n    return \"This is a 500\", 500\n    \nif __name__ == \"__main__\":\n    app.run(\"127.0.0.1\", 8080)\n\n```\n\nIf we run this above tiny application and try to hit ``` /res500 ``` endpoint, it will generate an opsgenie alert because we are monitoring for ``` 500 ```\nresponse status code and the given endpoint returns the same. \n\n![Screenshot 2021-12-05 at 4 54 55 PM](https://user-images.githubusercontent.com/16368427/144744662-8b638b1f-7237-4b86-bd24-c37808c495e8.png)\n\nThis is the alert we get out of the box using the bare minimum configuration we used above. As it can bee seen, flask-opsgenie decides for an appropriate alias\nfor this alert so that similar alerts can be grouped in future. It also provides several details in the details section like the path, method, url and response\nof the request and additionaly the host which served the request. The alias can always be overriden as well.\n\nIf we want we can provide several status codes to be monitored like : ``` ALERT_STATUS_CODES = [500, 501, 502] ```\nThis will generate an alert if any of the mentioned status codes is returned. So if we want to monitor for all the 5's status codes we can keep on mentioning\nall of them like ``` 500, 501, 502, 503 ...``` or even better we can use ``` ALERT_STATUS_CLASSES = [\"5XX\"] ``` instead of ``` ALERT_STATUS_CODES ```. As the\nname suggests ``` ALERT_STATUS_CLASSES ``` instructs flask-opsgenie to monitor for entire classes of status codes which in this case will be the ``` 5XX ``` class\nwhich means 500, 501, 502 and so on till 510. Isn't that cool?\nWe can also chose to monitor a given set of routes/endpoints, conversely we can chose to monitor all the endpoints for the response status code alert and decide\nto ignore a few. More on that later.\n\nWe can also configure flask-opsgnie such that it generates an opsegenie alert when a monitored route breaches response time latency. Lets see an example for that.\nFor this example let us consider the following flask snippet.\n\n```\nimport time\nimport os\nfrom flask import Flask\nfrom flask_opsgenie import FlaskOpsgenie\n\nclass FlaskOpsgenieConfig:\n\n    OPSGENIE_TOKEN = os.getenv(\"API_KEY\")\n    ALERT_TAGS = [\"flask_latency_alert\"]\n    ALERT_PRIORITY = \"P3\"\n    SERVICE_ID = \"my_flask_service\"\n    THRESHOLD_RESPONSE_TIME = 2000.0 # time is required in ms\n    RESPONSE_TIME_MONITORED_ENDPOINTS = [\"^\\/res_slow\\/\\d+\\/info\\/$\"]\n    RESPONDER = [{\n        \"type\": \"user\",\n        \"username\": \"neo@matrix\"\n    }]\n\napp = Flask(__name__)\napp.config.from_object(FlaskOpsgenieConfig())\nflask_opsgenie = FlaskOpsgenie(None)\nflask_opsgenie.init_app(app)\n\n@app.route(\"/res_slow/\u003cid_num\u003e/info/\", methods=[\"GET\"])\ndef res_slow(id_num):\n    time.sleep(3)\n    return f'I am slow, {id_num}', \n    \nif __name__ == \"__main__\":\n    app.run(\"127.0.0.1\", 8080)\n\n```\n\nOnce again, if we run this above tiny flask application and hit ```/res_slow/1/info/``` it will generate an opsgenie alert because the route takes more than\n2s or 2000ms to return a response.\n\n![Screenshot 2021-12-05 at 5 21 54 PM](https://user-images.githubusercontent.com/16368427/144745379-393d9389-7233-4b05-8939-3bfd62f689a3.png)\n\nAbove is the alert generated by flask-opsgenie for this example. Again, we have the same amount of details as before and a different alias this time to denote\nits an latency related alert. Also, we do notice that now we have two new config parameters. First is ```THRESHOLD_RESPONSE_TIME``` which takes latency\ntime threshold in ms and then we have ```RESPONSE_TIME_MONITORED_ENDPOINTS``` which takes a list of regexes to match against a route path. If the route matches\nwith any of the regexes present in the list, that route path will be monitored and an alert will be generated if it breaches the response latency,\n\nFinally, we can also generate alert when a route throws an exception for some reason. It might seem that we dont need to capture this situation since if a route\nraises an exception, the response returned will be 500/5XX and hence we can have an alert for that. However that is always not true with flask. If we use\nmultiple ```@app.after_request``` decorated methods and if somehow one of those methods fail to return the respnse object at the end, the response (status 5XX)\nwill not be sent back to the user. In such scenario this config option provided by flask-opsgenie can help us.\nAlso the generated alert will have the exception in the alert body which can come quite handy for the on-call engineer.\n\nThere are two cases to it:\n1. To raise alert on unhandled Exceptions:\n   For unhandled exceptions, flask has a beautiful way to handle it via decorator ```@app.errorhandler(Exception)```. User needs to call ```flask_opsgenie``` function with exception to raise the alert. No separate config is required\n\n2. To raise alert on handled Exceptions:\n   To raise alerts for handled exception, call function ```flask_opsgenie.raise_exception_alert``` with exceotion and stack-trace (if you want). You can also add function-name to it to make it more descriptive.\n \n\n```\n# Raise alert for unhandled Exceptions\n\nimport os, traceback\nfrom flask import Flask\nfrom flask_opsgenie import FlaskOpsgenie, AlertType\n\nclass FlaskOpsgenieConfig:\n\n    OPSGENIE_TOKEN = os.getenv(\"API_KEY\")\n    ALERT_TAGS = [\"flask_exception_alert\"]\n    ALERT_PRIORITY = \"P3\"\n    SERVICE_ID = \"my_flask_service\"\n    RESPONDER = [{\n        \"type\": \"user\",\n        \"username\": \"neo@matrix\"\n    }]\n    ALERT_ALIAS = \"handled_exception\"\n    ALERT_EXCEPTION_ALIAS = \"unhandled_exception\"\n\napp = Flask(__name__)\napp.config.from_object(FlaskOpsgenieConfig())\nflask_opsgenie = FlaskOpsgenie(None)\nflask_opsgenie.init_app(app)\n\n@app.errorhandler(Exception)\ndef exception_handler(e: Exception):\n    \"\"\"Handler for generic Exceptions occurring in the Application\"\"\"\n    \n    flask_opsgenie.raise_exception_alert(alert_type=AlertType.EXCEPTION, exception=e)\n    return {'Error': str(e)}, 500\n\n\n@app.route(\"/unhandledException\", methods=[\"GET\"])\ndef unhandled_exception_case():\n    a = 1/0\n    return \"I am assuming everything is fine, but there might be exception\", 200\n\n\n@app.route(\"/handledException\", methods=[\"GET\"])\ndef handled_exception_case():\n    try:\n        a = 1/0\n    except Exception as e:\n        flask_opsgenie.raise_exception_alert(alert_type=AlertType.MANUAL, exception=e, func_name=\"handle_exception_case\")\n\n    return \"I am assuming everything is fine, but there might be exception\", 200\n    \nif __name__ == \"__main__\":\n    app.run(\"127.0.0.1\", 8080)\n\n\n```\n\nIf we hit ```/res_ex```, flask_opsgenie will raise an alert since this route will be throwing a Division by Zero exception.\nThe difference between two alerts for two cases would be in ```Alias```. \n- Unhandled Exception: Alias format -\u003e ```SERVICE_ID-\u003cexception-name\u003e-ALERT_EXCEPTION_ALIAS```\n- Handled Exception: Alias format -\u003e ```SERVICE_ID-\u003cfuncname\u003e-\u003cexception-name\u003e-ALERT_ALIAS```\n\n![Screenshot 2021-12-05 at 5 44 31 PM](/Users/sgupta8/Desktop/Screenshot 2022-01-21 at 1.44.35 PM.png)\n\n### Support for gevent Exceptions\nAnother case for exception handling is when you are using ```gevent``` in flask app. In case of ```gevent```, exception will not propagate to main thread, hence flask-opsgenie will not be able to raise any opsgenie Alert. \nTo handle this, user needs to invoke a callback to link gevent exception to main thread. \n\n```\n# Raise alert for gevent Exceptions\n\nimport os, traceback\nfrom flask import Flask\nfrom flask_opsgenie import FlaskOpsgenie, AlertType\n\nclass FlaskOpsgenieConfig:\n\n    OPSGENIE_TOKEN = os.getenv(\"API_KEY\")\n    ALERT_TAGS = [\"flask_exception_alert\"]\n    ALERT_PRIORITY = \"P3\"\n    SERVICE_ID = \"my_flask_service\"\n    RESPONDER = [{\n        \"type\": \"user\",\n        \"username\": \"neo@matrix\"\n    }]\n    ALERT_ALIAS = \"handled_exception\"\n    ALERT_EXCEPTION_ALIAS = \"unhandled_exception\"\n\napp = Flask(__name__)\napp.config.from_object(FlaskOpsgenieConfig())\nflask_opsgenie = FlaskOpsgenie(None)\nflask_opsgenie.init_app(app)\n\n@app.errorhandler(Exception)\ndef exception_handler(e: Exception):\n    \"\"\"Handler for generic Exceptions occurring in the Application\"\"\"\n    \n    flask_opsgenie.raise_exception_alert(alert_type=AlertType.EXCEPTION, exception=e)\n    return {'Error': str(e)}, 500\n\n\n@app.route(\"/geventException\", methods=[\"GET\"])\ndef unhandled_exception_case():\n    g = gevent.spawn(inner_func)\n    flask_opsgenie.gevent_exception_callback(g)\n    return \"I am assuming everything is fine, but there might be exception\", 200\n\n\ndef inner_func():\n    time.sleep(2)\n    a = 1/0\n\n    \nif __name__ == \"__main__\":\n    app.run(\"127.0.0.1\", 8080)\n```\n\n## Flask-opsgenie configuration in details\n\nAs already shown in the quick start guide, initialising flask-opsgenie is pretty easy just like any other flask extention. We can either pass the flask app\nobject to the FlaskOpsgenie constructor or use the the init method of initialising flask-opsgenie. We can load the config as an object or from a config file.\n\nIn this section we will go through all the different config option that flask-opsgenie provides, how we can use them and what default values they assume.\n\n### Config options provided by flask-opsgenie\n\n- **ALERT_STATUS_CODES** : This takes a list of status codes. Our flask service endpoints will be monitored against these response status codes. By default all\nthe endpoints/routes will be monitored, but this can be controlled, as mentioned below.\n\n- **ALERT_STATUS_CLASS** : This takes a list of response status classes like ```5XX, 4XX or 3XX``` etc. For example if the provided value is ```[\"5XX\", \"4XX\"]```\nany request throwing a 501 or 502 or 404 or 403 etc will raise opsgenie alert. Again by default if this param is present, all the route response status codes\nwill be monitored, however this too can be controlled. If both ```ALERT_STATUS_CODES``` and ```ALERT_STATUS_CLASS``` are provided, then ```ALERT_STATUS_CODES```\nwill be given priority. That is if we are monitoring for both 501 and 5XX, there will be only one alert generated and not two.\n\n- **MONITORED_ENDPOINTS** : This takes in a list of regexes. With this we can limit the endpoints that will be monitored for or whose response status code/class\nwill be matched against the provided params. The request endpoints will be matched against the given list of regexes and only the matching paths will be\nevaluated against the given rules. It is to be noted that the given regex should be provided keeping only the request/route path in mind, niether the complete\nurl nor the query params. For example if the requested url is ```https://mydomain.com/blog/1/info?theme=dark``` only ```/blog/1/info``` will be matched against\nthe list of regex patterns provided.\n\n- **IGNORED_ENDPOINTS** : This takes a list of regexes. With this we can ignore a given set of route paths from being monitored for the response status\ncode/class alerts. If a path matches any of the regex present in this list, it wont be evaluated aginst any of the above mentioned rules. For this as well,\nonly the request path is matched against the pattern, not the url or the arguments.\n\n- **THRESHOLD_RESPONSE_TIME** : This takes in a int or float and the number is interpretated as time duration in **milliseconds**. With this param its mandatory\nto provide ```RESPONSE_TIME_MONITORED_ENDPOINTS``` as well which once again takes in a list of regex patterns to match against the requested route paths. So how\nits supposed to work is for every request path that matches any of the regex patterns present in ```RESPONSE_TIME_MONITORED_ENDPOINTS```, flask-opsgenie will\ncompare the response time of that request against ```THRESHOLD_RESPONSE_TIME```, and if the response time exceeds this value then an opsgenie alert will be\ngenerated.\n\n- **RESPONSE_TIME_MONITORED_ENDPOINTS** : As already mentioned in the previous line, this also takes a list of regex patterns to match against request paths\n(not to mention, only paths) for monitoring selective route paths against response time latency.\n\n- **OPSGENIE_TOKEN** : This is the opsgenie REST API integration token which flask-opsgenie will use on your behalf to invoke opsgenie REST API.\n\n- **OPSGENIE_API_BASE** : This takes in a string representing the Opsgenie REST API base. By default its Opsgenie US, however if we want we can override it\nwith something else like EU.\n\n- **ALERT_TAGS** : This takes in a list of strings which will be put as tags on the generated alert.\n\n- **ALERT_DETAILS** : It takes a dictionary of keys and values. These are details provided along with the alert body. Flask-opsgenie will by default provided\nsome details like request url, path, method, etc as can be seen in the screenshots above. Whatever we mention in this dictionary will be added over and above\nthe default ones.\n\n- **SERVICE_ID** : As the name suggests, this option takes in a string as a service id. If this is not provided, flask-opsgenie comes up with a default service\nname which is ```flask-service-{host}```, where host is basically the hostname of the box or conatiner where the service is running.\n\n- **ALERT_ALIAS** : Takes in a string and uses it as the default alert alias when the alert type specific aliases are not present. If this too is not present,\nthen flask-opsgenie generates and uses a default alias depedning on the alert type.\n\n- **ALERT_STATUS_ALIAS** : Takes in a string and uses it as the alias for an alert generated for unwanted response status code. If this is not present then\n```ALERT_ALIAS``` value is used. If that too is not present then ```{service_id}-response-status-alert``` is used as the alias.\n\n- **ALERT_LATENCY_ALIAS** :  Takes in a string and uses it as the alias for an alert generated for breach of latency threshold. If this is not present then\n```ALERT_ALIAS``` value is used. If that too is not present then ```{service_id}-esponse-latency-alert``` is used as the alias.\n\n- **ALERT_EXCEPTION_ALIAS** : Takes in a string and uses it as the alias for an alert generated in response to an exception from a route. If this is not\npresent then ```ALERT_ALIAS``` value is used. If that too is not present then ```{service_id}-exception-alert``` is used as the alias.\n\n- **ALERT_PRIORITY** : One of ```P1|P2|P3|P4|P5```. Default is P4.\n\n- **FORWARDED_HEADER_KEYS** : Takes a list of request header keys and add its value to Opsgenie Alert in detail section. Usually, it is used to send ```request_id``` from headers to help in tracing\n\n- **RESPONDER** : The responder of your alert. Takes in a list of dictionary same as that accepted by the Opsgenie alert API. More can be found\n\u003ca href=\"https://docs.opsgenie.com/docs/alert-api\"\u003e here \u003c/a\u003e under responder field example. An example for adding an user can be\n```[{\"type\": \"user\",\"username\": \"user@domain.com\"}]```\n\n\n\n## Enriching Opsgenie Alert with extra information\n\nSometimes, it is required to add extra details to Opsgenie alerts via alert-details. You can add any details in key:value pair via Flask-Opsgenie function ```raise_exception_alert```\n\n- **extra_props** : This is a dictionary type object. You can send any data you want and it'll be added to Opsgenie alert in detail section. Good example can be function name. \n\n- **alert_priority** : Alert-Priority can be overridden while invoking function ```raise_exception_alert```. One of ```P1|P2|P3|P4|P5```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjmgit%2Fflask-opsgenie","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdjmgit%2Fflask-opsgenie","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjmgit%2Fflask-opsgenie/lists"}