diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..19c458d --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,7 @@ +repos: +- repo: https://github.com/psf/black + rev: 19.10b0 + hooks: + - id: black + types: [python] + language_version: python3.7 \ No newline at end of file diff --git a/Makefile b/Makefile index 5b4870d..6f428ec 100644 --- a/Makefile +++ b/Makefile @@ -9,4 +9,7 @@ disttest: package python3 -m twine upload --repository-url https://test.pypi.org/legacy/ dist/* distprod: package - python3 -m twine upload dist/* \ No newline at end of file + python3 -m twine upload dist/* + +clean: + rm -rf .pytest_cache/ dist/ *.egg-info/ \ No newline at end of file diff --git a/README.md b/README.md index 6a4b77b..db50fcb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,12 @@ # GitHub Status Checker +[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) +[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) +![Tests](https://github.com/rapid7/github-status-checker/workflows/Tests/badge.svg) +![Python Lint](https://github.com/rapid7/github-status-checker/workflows/Python%20Lint/badge.svg) +![Markdown Lint](https://github.com/rapid7/github-status-checker/workflows/Markdown%20Lint/badge.svg) + ## What this is A tool and Python module for checking the status of GitHub. @@ -21,8 +27,18 @@ moose@rapid7:~$ github-status webhooks Service 'Webhooks' is currently operational! ``` +## Contributions + +Contributions are welcome! This project utilizes [black](https://github.com/psf/black) +and [pre-commit](https://pre-commit.com/) for handling code +style. Simply follow the instructions for installing pre-commit and +run `pre-commit install` in the repository after cloning and you will +be on your way to contributing! + ## Changelog +* 1.0.2 - Update to handle crash on outage report | Code style: black +| Add contribution section * 1.0.1 - Update homepage and author name * 1.0.0 - Swap dataclasses for traditional classes for greater Python version compatibility (Python 3.x+) diff --git a/github_status_checker/models/affected_component.py b/github_status_checker/models/affected_component.py new file mode 100644 index 0000000..156ee75 --- /dev/null +++ b/github_status_checker/models/affected_component.py @@ -0,0 +1,10 @@ +class AffectedComponent: + def __init__(self, code: str, name: str, old_status: str, new_status: str): + self.code = code + self.name = name + self.old_status = old_status + self.new_status = new_status + + @classmethod + def from_json(cls, json_: dict): + return cls(**json_) diff --git a/github_status_checker/models/incident.py b/github_status_checker/models/incident.py index 5725b9f..c676df1 100644 --- a/github_status_checker/models/incident.py +++ b/github_status_checker/models/incident.py @@ -1,38 +1,45 @@ from typing import Optional from github_status_checker.models.incident_update import IncidentUpdate +from github_status_checker.models.component import Component class Incident: - - def __init__(self, - created_at: str, - id: str, - impact: str, - incident_updates: [IncidentUpdate], - monitoring_at: Optional[str], - name: str, - page_id: str, - resolved_at: Optional[str], - shortlink: str, - status: str, - updated_at: str): + def __init__( + self, + created_at: str, + id: str, + impact: str, + incident_updates: [IncidentUpdate], + components: [Component], + monitoring_at: Optional[str], + name: str, + page_id: str, + resolved_at: Optional[str], + shortlink: str, + status: str, + started_at: str, + updated_at: str, + ): self.created_at = created_at self.id = id self.impact = impact self.incident_updates = incident_updates + self.components = components self.monitoring_at = monitoring_at self.name = name self.page_id = page_id self.resolved_at = resolved_at self.shortlink = shortlink self.status = status + self.started_at = started_at self.updated_at = updated_at @classmethod def from_json(cls, json_: dict): incident = cls(**json_) - incident.incident_updates = \ - [IncidentUpdate.from_json(json_=iu) for iu in json_.get("incident_updates")] + incident.incident_updates = [ + IncidentUpdate.from_json(json_=iu) for iu in json_.get("incident_updates") + ] return incident diff --git a/github_status_checker/models/incident_update.py b/github_status_checker/models/incident_update.py index e34fa47..dfc1f05 100644 --- a/github_status_checker/models/incident_update.py +++ b/github_status_checker/models/incident_update.py @@ -1,3 +1,6 @@ +from github_status_checker.models.affected_component import AffectedComponent + + class IncidentUpdate: body: str created_at: str @@ -7,18 +10,28 @@ class IncidentUpdate: status: str updated_at: str - def __init__(self, - body: str, - created_at: str, - display_at: str, - id: str, - incident_id: str, - status: str, - updated_at: str): + def __init__( + self, + body: str, + created_at: str, + display_at: str, + affected_components: [AffectedComponent], + deliver_notifications: bool, + custom_tweet: str, + tweet_id: str, + id: str, + incident_id: str, + status: str, + updated_at: str, + ): self.body = body self.created_at = created_at self.display_at = display_at + self.affected_components = affected_components + self.deliver_notifications = deliver_notifications + self.custom_tweet = custom_tweet + self.tweet_id = str(tweet_id) self.id = id self.incident_id = incident_id self.status = status diff --git a/setup.py b/setup.py index f6b80db..19a739c 100644 --- a/setup.py +++ b/setup.py @@ -5,23 +5,19 @@ setup( name="github_status_checker", - version="1.0.1", + version="1.0.2", description="Python module/tool for checking the status of GitHub.", long_description=long_description, long_description_content_type="text/markdown", - author='Rapid7 Integration Alliance', - author_email='integrationalliance@rapid7.com', - url='https://github.com/rapid7/github-status-checker', - license='MIT', + author="Rapid7 Integration Alliance", + author_email="integrationalliance@rapid7.com", + url="https://github.com/rapid7/github-status-checker", + license="MIT", packages=find_packages(), - install_requires=[ - "requests~=2.0" - ], + install_requires=["requests~=2.0"], include_package_data=True, entry_points={ - 'console_scripts': [ - 'github-status=github_status_checker.__main__:main' - ] + "console_scripts": ["github-status=github_status_checker.__main__:main"] }, classifiers=[ "Programming Language :: Python :: 3", @@ -34,6 +30,6 @@ "Topic :: Software Development :: Build Tools", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Software Development :: Version Control :: Git", - "Topic :: System :: Networking :: Monitoring" - ], + "Topic :: System :: Networking :: Monitoring", + ], ) diff --git a/tests/test.py b/tests/test.py index 27124ab..7321f5b 100644 --- a/tests/test.py +++ b/tests/test.py @@ -6,7 +6,6 @@ class TestCheckInvalidArg(TestCase): - def setUp(self) -> None: pass @@ -16,7 +15,6 @@ def test_check(self): class TestJSONDeserializeSummary(TestCase): - def setUp(self) -> None: pass @@ -28,3 +26,219 @@ def test_deserialize_good(self): except TypeError: self.fail() + +class TestOutagePayload(TestCase): + def setUp(self) -> None: + self.json = """{ + "page": { + "id": "kctbh9vrtdwd", + "name": "GitHub", + "url": "https://www.githubstatus.com", + "time_zone": "Etc/UTC", + "updated_at": "2020-04-02T20:37:08.838Z" + }, + "components": [ + { + "id": "8l4ygp009s5s", + "name": "Git Operations", + "status": "major_outage", + "created_at": "2017-01-31T20:05:05.370Z", + "updated_at": "2020-04-02T20:26:21.656Z", + "position": 1, + "description": "Performance of git clones, pulls, pushes, and associated operations", + "showcase": true, + "group_id": null, + "page_id": "kctbh9vrtdwd", + "group": false, + "only_show_if_degraded": false + }, + { + "id": "brv1bkgrwx7q", + "name": "API Requests", + "status": "major_outage", + "created_at": "2017-01-31T20:01:46.621Z", + "updated_at": "2020-04-02T20:18:20.643Z", + "position": 2, + "description": "Requests for GitHub APIs", + "showcase": true, + "group_id": null, + "page_id": "kctbh9vrtdwd", + "group": false, + "only_show_if_degraded": false + }, + { + "id": "4230lsnqdsld", + "name": "Webhooks", + "status": "major_outage", + "created_at": "2019-11-13T18:00:24.256Z", + "updated_at": "2020-04-02T20:37:08.834Z", + "position": 3, + "description": "Real time HTTP callbacks of user-generated and system events", + "showcase": true, + "group_id": null, + "page_id": "kctbh9vrtdwd", + "group": false, + "only_show_if_degraded": false + }, + { + "id": "0l2p9nhqnxpd", + "name": "Visit www.githubstatus.com for more information", + "status": "operational", + "created_at": "2018-12-05T19:39:40.838Z", + "updated_at": "2019-11-13T18:02:47.782Z", + "position": 4, + "description": null, + "showcase": false, + "group_id": null, + "page_id": "kctbh9vrtdwd", + "group": false, + "only_show_if_degraded": false + }, + { + "id": "kr09ddfgbfsf", + "name": "Issues, PRs, Projects", + "status": "major_outage", + "created_at": "2017-01-31T20:01:46.638Z", + "updated_at": "2020-04-02T20:18:21.177Z", + "position": 5, + "description": "Web requests for github.com UI and services", + "showcase": true, + "group_id": null, + "page_id": "kctbh9vrtdwd", + "group": false, + "only_show_if_degraded": false + }, + { + "id": "br0l2tvcx85d", + "name": "GitHub Actions", + "status": "partial_outage", + "created_at": "2019-11-13T18:02:19.432Z", + "updated_at": "2020-04-02T20:21:56.716Z", + "position": 6, + "description": "Workflows, Compute and Orchestration for GitHub Actions", + "showcase": true, + "group_id": null, + "page_id": "kctbh9vrtdwd", + "group": false, + "only_show_if_degraded": false + }, + { + "id": "st3j38cctv9l", + "name": "GitHub Packages", + "status": "major_outage", + "created_at": "2019-11-13T18:02:40.064Z", + "updated_at": "2020-04-02T20:36:52.738Z", + "position": 7, + "description": "API requests and webhook delivery for GitHub Packages", + "showcase": true, + "group_id": null, + "page_id": "kctbh9vrtdwd", + "group": false, + "only_show_if_degraded": false + }, + { + "id": "vg70hn9s2tyj", + "name": "GitHub Pages", + "status": "operational", + "created_at": "2017-01-31T20:04:33.923Z", + "updated_at": "2020-03-12T15:51:14.866Z", + "position": 8, + "description": "Frontend application and API servers for Pages builds", + "showcase": true, + "group_id": null, + "page_id": "kctbh9vrtdwd", + "group": false, + "only_show_if_degraded": false + }, + { + "id": "5l5rlzqm4yzy", + "name": "Other", + "status": "operational", + "created_at": "2019-11-13T18:03:05.012Z", + "updated_at": "2020-03-06T00:22:12.900Z", + "position": 9, + "description": "Other", + "showcase": false, + "group_id": null, + "page_id": "kctbh9vrtdwd", + "group": false, + "only_show_if_degraded": false + } + ], + "incidents": [ + { + "id": "80d0cs6kpsps", + "name": "Incident on 2020-04-02 20:20 UTC", + "status": "investigating", + "created_at": "2020-04-02T20:20:54.013Z", + "updated_at": "2020-04-02T20:26:36.356Z", + "monitoring_at": null, + "resolved_at": null, + "impact": "major", + "shortlink": "http://stspg.io/n0wskg2n6bvy", + "started_at": "2020-04-02T20:20:54.005Z", + "page_id": "kctbh9vrtdwd", + "incident_updates": [ + { + "id": "yqsdhyw44qzj", + "status": "investigating", + "body": "We are investigating reports of service unavailability.", + "incident_id": "80d0cs6kpsps", + "created_at": "2020-04-02T20:26:36.354Z", + "updated_at": "2020-04-02T20:26:36.354Z", + "display_at": "2020-04-02T20:26:36.354Z", + "affected_components": null, + "deliver_notifications": true, + "custom_tweet": null, + "tweet_id": null + }, + { + "id": "bd69p75gd9y8", + "status": "investigating", + "body": "We are investigating reports of degraded performance.", + "incident_id": "80d0cs6kpsps", + "created_at": "2020-04-02T20:20:54.071Z", + "updated_at": "2020-04-02T20:20:54.071Z", + "display_at": "2020-04-02T20:20:54.071Z", + "affected_components": [ + { + "code": "0l2p9nhqnxpd", + "name": "Visit www.githubstatus.com for more information", + "old_status": "operational", + "new_status": "operational" + } + ], + "deliver_notifications": true, + "custom_tweet": null, + "tweet_id": null + } + ], + "components": [ + { + "id": "0l2p9nhqnxpd", + "name": "Visit www.githubstatus.com for more information", + "status": "operational", + "created_at": "2018-12-05T19:39:40.838Z", + "updated_at": "2019-11-13T18:02:47.782Z", + "position": 4, + "description": null, + "showcase": false, + "group_id": null, + "page_id": "kctbh9vrtdwd", + "group": false, + "only_show_if_degraded": false + } + ] + } + ], + "scheduled_maintenances": [], + "status": { + "indicator": "major", + "description": "Partial System Outage" + } +} +""" + + def test_serialize(self): + summary = Summary.from_json(json_=json.loads(self.json)) + print(summary)