add get requests and change HTTP OK to HTTP No Content

This commit is contained in:
Evgenii Alekseev 2021-03-17 05:20:20 +03:00
parent 0937a9a4b5
commit 5a340146bb
7 changed files with 91 additions and 16 deletions

View File

@ -52,6 +52,13 @@ class Watcher:
''' '''
return [pair for pair in self.known.values()] return [pair for pair in self.known.values()]
def get(self, base: str) -> Tuple[Package, BuildStatus]:
'''
get current package base build status
:return: package and its status
'''
return self.known[base]
def load(self) -> None: def load(self) -> None:
''' '''
load packages from local repository. In case if last status is known, it will use it load packages from local repository. In case if last status is known, it will use it

View File

@ -21,7 +21,6 @@ import logging
import requests import requests
from dataclasses import asdict from dataclasses import asdict
from typing import Any, Dict
from ahriman.core.watcher.client import Client from ahriman.core.watcher.client import Client
from ahriman.models.build_status import BuildStatusEnum from ahriman.models.build_status import BuildStatusEnum
@ -67,7 +66,7 @@ class WebClient(Client):
:param package: package properties :param package: package properties
:param status: current package build status :param status: current package build status
''' '''
payload: Dict[str, Any] = { payload = {
'status': status.value, 'status': status.value,
'package': asdict(package) 'package': asdict(package)
} }
@ -95,7 +94,7 @@ class WebClient(Client):
:param base: package base to update :param base: package base to update
:param status: current package build status :param status: current package build status
''' '''
payload: Dict[str, Any] = {'status': status.value} payload = {'status': status.value}
try: try:
response = requests.post(self._package_url(base), json=payload) response = requests.post(self._package_url(base), json=payload)
@ -108,7 +107,7 @@ class WebClient(Client):
update ahriman status itself update ahriman status itself
:param status: current ahriman status :param status: current ahriman status
''' '''
payload: Dict[str, Any] = {'status': status.value} payload = {'status': status.value}
try: try:
response = requests.post(self._ahriman_url(), json=payload) response = requests.post(self._ahriman_url(), json=payload)

View File

@ -34,21 +34,27 @@ def setup_routes(application: Application) -> None:
GET / get build status page GET / get build status page
GET /index.html same as above GET /index.html same as above
GET /api/v1/ahriman get current service status
POST /api/v1/ahriman update service status POST /api/v1/ahriman update service status
GET /api/v1/packages get all known packages
POST /api/v1/packages force update every package from repository POST /api/v1/packages force update every package from repository
POST /api/v1/package/:base update package base status
DELETE /api/v1/package/:base delete package base from status page DELETE /api/v1/package/:base delete package base from status page
GET /api/v1/package/:base get package base status
POST /api/v1/package/:base update package base status
:param application: web application instance :param application: web application instance
''' '''
application.router.add_get('/', IndexView) application.router.add_get('/', IndexView)
application.router.add_get('/index.html', IndexView) application.router.add_get('/index.html', IndexView)
application.router.add_get('/api/v1/ahriman', AhrimanView)
application.router.add_post('/api/v1/ahriman', AhrimanView) application.router.add_post('/api/v1/ahriman', AhrimanView)
application.router.add_get('/api/v1/packages', PackagesView)
application.router.add_post('/api/v1/packages', PackagesView) application.router.add_post('/api/v1/packages', PackagesView)
application.router.add_delete('/api/v1/packages/{package}', PackageView) application.router.add_delete('/api/v1/packages/{package}', PackageView)
application.router.add_get('/api/v1/packages/{package}', PackageView)
application.router.add_post('/api/v1/packages/{package}', PackageView) application.router.add_post('/api/v1/packages/{package}', PackageView)

View File

@ -17,7 +17,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
from aiohttp.web import HTTPBadRequest, HTTPOk, Response from aiohttp.web import HTTPBadRequest, HTTPNoContent, Response, json_response
from ahriman.models.build_status import BuildStatusEnum from ahriman.models.build_status import BuildStatusEnum
from ahriman.web.views.base import BaseView from ahriman.web.views.base import BaseView
@ -28,6 +28,13 @@ class AhrimanView(BaseView):
service status web view service status web view
''' '''
async def get(self) -> Response:
'''
get current service status
:return: 200 with service status object
'''
return json_response(AhrimanView.status_view(self.service.status))
async def post(self) -> Response: async def post(self) -> Response:
''' '''
update service status update service status
@ -37,7 +44,7 @@ class AhrimanView(BaseView):
"status": "unknown", # service status string, must be valid `BuildStatusEnum` "status": "unknown", # service status string, must be valid `BuildStatusEnum`
} }
:return: 200 on success :return: 204 on success
''' '''
data = await self.request.json() data = await self.request.json()
@ -48,4 +55,4 @@ class AhrimanView(BaseView):
self.service.update_self(status) self.service.update_self(status)
return HTTPOk() return HTTPNoContent()

View File

@ -17,9 +17,14 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
from dataclasses import asdict
from typing import Any, Dict
from aiohttp.web import View from aiohttp.web import View
from ahriman.core.watcher.watcher import Watcher from ahriman.core.watcher.watcher import Watcher
from ahriman.models.build_status import BuildStatus
from ahriman.models.package import Package
class BaseView(View): class BaseView(View):
@ -34,3 +39,28 @@ class BaseView(View):
''' '''
watcher: Watcher = self.request.app['watcher'] watcher: Watcher = self.request.app['watcher']
return watcher return watcher
@staticmethod
def package_view(package: Package, status: BuildStatus) -> Dict[str, Any]:
'''
generate json package view
:param package: package definitions
:param status: package build status
:return: json-friendly dictionary
'''
return {
'status': BaseView.status_view(status),
'package': asdict(package)
}
@staticmethod
def status_view(status: BuildStatus) -> Dict[str, Any]:
'''
generate json status view
:param status: build status
:return: json-friendly dictionary
'''
return {
'status': status.status.value,
'timestamp': status.timestamp
}

View File

@ -17,7 +17,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
from aiohttp.web import HTTPBadRequest, HTTPOk, Response from aiohttp.web import HTTPBadRequest, HTTPNoContent, HTTPNotFound, Response, json_response
from ahriman.models.build_status import BuildStatusEnum from ahriman.models.build_status import BuildStatusEnum
from ahriman.models.package import Package from ahriman.models.package import Package
@ -29,15 +29,30 @@ class PackageView(BaseView):
package base specific web view package base specific web view
''' '''
async def get(self) -> Response:
'''
get current package base status
:return: 200 with package description on success
'''
base = self.request.match_info['package']
try:
package, status = self.service.get(base)
except KeyError:
raise HTTPNotFound()
response = PackageView.package_view(package, status)
return json_response(response)
async def delete(self) -> Response: async def delete(self) -> Response:
''' '''
delete package base from status page delete package base from status page
:return: 200 on success :return: 204 on success
''' '''
base = self.request.match_info['package'] base = self.request.match_info['package']
self.service.remove(base) self.service.remove(base)
return HTTPOk() return HTTPNoContent()
async def post(self) -> Response: async def post(self) -> Response:
''' '''
@ -50,7 +65,7 @@ class PackageView(BaseView):
# Must be supplied in case if package base is unknown # Must be supplied in case if package base is unknown
} }
:return: 200 on success :return: 204 on success
''' '''
base = self.request.match_info['package'] base = self.request.match_info['package']
data = await self.request.json() data = await self.request.json()
@ -66,4 +81,4 @@ class PackageView(BaseView):
except KeyError: except KeyError:
raise HTTPBadRequest(text=f'Package {base} is unknown, but no package body set') raise HTTPBadRequest(text=f'Package {base} is unknown, but no package body set')
return HTTPOk() return HTTPNoContent()

View File

@ -17,7 +17,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
from aiohttp.web import HTTPOk, Response from aiohttp.web import HTTPNoContent, Response, json_response
from ahriman.web.views.base import BaseView from ahriman.web.views.base import BaseView
@ -27,11 +27,22 @@ class PackagesView(BaseView):
global watcher view global watcher view
''' '''
async def get(self) -> Response:
'''
get current packages status
:return: 200 with package description on success
'''
response = [
PackagesView.package_view(package, status)
for package, status in self.service.packages
]
return json_response(response)
async def post(self) -> Response: async def post(self) -> Response:
''' '''
reload all packages from repository. No parameters supported here reload all packages from repository. No parameters supported here
:return: 200 on success :return: 204 on success
''' '''
self.service.load() self.service.load()
return HTTPOk() return HTTPNoContent()