Skip to content

Commit

Permalink
global: add runs endpoint (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
wgresshoff authored May 14, 2024
1 parent c7e82bc commit d225bae
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 24 deletions.
17 changes: 16 additions & 1 deletion invenio_jobs/ext.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2024 CERN.
# Copyright (C) 2024 University of Münster.
#
# Invenio-Jobs is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.
Expand All @@ -13,10 +14,19 @@
from .resources import (
JobsResource,
JobsResourceConfig,
RunsResource,
RunsResourceConfig,
TasksResource,
TasksResourceConfig,
)
from .services import JobsService, JobsServiceConfig, TasksService, TasksServiceConfig
from .services import (
JobsService,
JobsServiceConfig,
RunsService,
RunsServiceConfig,
TasksService,
TasksServiceConfig,
)


class InvenioJobs:
Expand All @@ -43,11 +53,15 @@ def init_config(self, app):
def init_services(self, app):
"""Initialize services."""
self.service = JobsService(JobsServiceConfig.build(app))
self.runs_service = RunsService(RunsServiceConfig.build(app))
self.tasks_service = TasksService(TasksServiceConfig.build(app))

def init_resource(self, app):
"""Initialize resources."""
self.jobs_resource = JobsResource(JobsResourceConfig.build(app), self.service)
self.runs_resource = RunsResource(
RunsResourceConfig.build(app), self.runs_service
)
self.tasks_resource = TasksResource(
TasksResourceConfig.build(app), self.tasks_service
)
Expand All @@ -60,4 +74,5 @@ def finalize_app(app):

# services
rr_ext.registry.register(ext.service, service_id="jobs")
rr_ext.registry.register(ext.runs_service, service_id="runs")
rr_ext.registry.register(ext.tasks_service, service_id="tasks")
7 changes: 5 additions & 2 deletions invenio_jobs/resources/__init__.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2024 CERN.
# Copyright (C) 2024 University of Münster.
#
# Invenio-Jobs is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.

"""Jobs resources."""

from .config import JobsResourceConfig, TasksResourceConfig
from .resources import JobsResource, TasksResource
from .config import JobsResourceConfig, RunsResourceConfig, TasksResourceConfig
from .resources import JobsResource, RunsResource, TasksResource

__all__ = (
"JobsResource",
"JobsResourceConfig",
"TasksResource",
"TasksResourceConfig",
"RunsResource",
"RunsResourceConfig",
)
31 changes: 29 additions & 2 deletions invenio_jobs/resources/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2024 CERN.
# Copyright (C) 2024 University of Münster.
#
# Invenio-Jobs is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.
Expand Down Expand Up @@ -37,15 +38,41 @@ class JobsResourceConfig(ResourceConfig, ConfiguratorMixin):
url_prefix = "/jobs"
routes = {
"list": "",
"item": "/<id>",
"item": "/<job_id>",
}

# Request parsing
request_read_args = {}
request_view_args = {"id": ma.fields.Int()}
request_view_args = {"job_id": ma.fields.UUID()}
request_search_args = JobsSearchRequestArgsSchema

error_handlers = {
**ErrorHandlersMixin.error_handlers,
# TODO: Add custom error handlers here
}


class RunsResourceConfig(ResourceConfig, ConfiguratorMixin):
"""Runs resource config."""

# Blueprint configuration
blueprint_name = "job_runs"
url_prefix = ""

routes = {
"list": "/jobs/<job_id>/runs",
"item": "/jobs/<job_id>/runs/<run_id>",
"logs_list": "/jobs/<job_id>/runs/<run_id>/logs",
"actions_stop": "/jobs/<job_id>/runs/<run_id>/actions/stop",
}

# Request parsing
request_view_args = {
"job_id": ma.fields.UUID(),
"run_id": ma.fields.UUID(),
}

error_handlers = {
**ErrorHandlersMixin.error_handlers,
# TODO: Add custom error handlers here
}
31 changes: 16 additions & 15 deletions invenio_jobs/resources/resources.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2024 CERN.
# Copyright (C) 2024 University of Münster.
#
# Invenio-Jobs is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.
Expand Down Expand Up @@ -59,7 +60,7 @@ def __init__(self, config, service):
self.service = service

def create_url_rules(self):
"""Create the URL rules for the OAI-PMH server resource."""
"""Create the URL rules for the jobs resource."""
routes = self.config.routes
url_rules = [
route("GET", routes["list"], self.search),
Expand Down Expand Up @@ -101,7 +102,7 @@ def read(self):
"""Read an item."""
item = self.service.read(
g.identity,
resource_requestctx.view_args["id"],
resource_requestctx.view_args["job_id"],
)
return item.to_dict(), 200

Expand All @@ -113,7 +114,7 @@ def update(self):
"""Update an item."""
item = self.service.update(
g.identity,
resource_requestctx.view_args["id"],
resource_requestctx.view_args["job_id"],
resource_requestctx.data,
)
return item.to_dict(), 200
Expand All @@ -124,7 +125,7 @@ def delete(self):
"""Delete an item."""
self.service.delete(
g.identity,
resource_requestctx.view_args["id"],
resource_requestctx.view_args["job_id"],
)
return "", 204

Expand All @@ -138,14 +139,13 @@ def __init__(self, config, service):
self.service = service

def create_url_rules(self):
"""Create the URL rules for the OAI-PMH server resource."""
"""Create the URL rules for runs resource."""
routes = self.config.routes
url_rules = [
route("GET", routes["list"], self.search),
route("POST", routes["list"], self.create),
route("GET", routes["item"], self.read),
route("PUT", routes["item"], self.update),
route("DELETE", routes["item"], self.delete),
route("GET", routes["runs"], self.search),
route("POST", routes["runs"], self.create),
route("DELETE", routes["run_item"], self.delete),
route("GET", routes["logs"], self.logs),
]

return url_rules
Expand Down Expand Up @@ -176,13 +176,14 @@ def create(self):

@request_view_args
@response_handler()
def read(self):
def logs(self):
"""Read an item."""
item = self.service.read(
g.identity,
resource_requestctx.view_args["id"],
identity = g.identity
hits = self.service.search(
identity=identity,
params=resource_requestctx.args,
)
return item.to_dict(), 200
return hits.to_dict(), 200

@request_headers
@request_view_args
Expand Down
7 changes: 5 additions & 2 deletions invenio_jobs/services/__init__.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2024 CERN.
# Copyright (C) 2024 University of Münster.
#
# Invenio-Jobs is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.

"""Services."""

from .config import JobsServiceConfig, TasksServiceConfig
from .config import JobsServiceConfig, RunsServiceConfig, TasksServiceConfig
from .schema import JobSchema
from .services import JobsService, TasksService
from .services import JobsService, RunsService, TasksService

__all__ = (
"JobSchema",
"JobsService",
"JobsServiceConfig",
"RunsService",
"RunsServiceConfig",
"TasksService",
"TasksServiceConfig",
)
35 changes: 34 additions & 1 deletion invenio_jobs/services/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2024 CERN.
# Copyright (C) 2024 University of Münster.
#
# Invenio-Jobs is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.
Expand All @@ -18,7 +19,7 @@

from ..models import Job, Run
from .links import JobLink
from .permissions import JobPermissionPolicy, TasksPermissionPolicy
from .permissions import JobPermissionPolicy, RunPermissionPolicy, TasksPermissionPolicy
from .schema import JobSchema


Expand Down Expand Up @@ -73,3 +74,35 @@ class JobsServiceConfig(ServiceConfig, ConfiguratorMixin):
}

links_search = pagination_links("{+api}/jobs{?args*}")


class RunsServiceConfig(ServiceConfig, ConfiguratorMixin):
"""Service factory configuration."""

# Common configuration
service_id = "runs"
permission_policy_cls = RunPermissionPolicy

# TODO: See if we need to define custom Job result item and list classes
result_item_cls = RecordItem
result_list_cls = RecordList

# Record specific configuration
record_cls = Run

# TODO: See if these are needed since we don't index jobs
# indexer_cls = None
# indexer_queue_name = None
# index_dumper = None

# Search configuration
search = JobSearchOptions

# Service schema
schema = JobSchema

links_item = {
"self": JobLink("{+api}/jobs/{job_id}/runs/{run_id}"),
"stop": JobLink("{+api}/jobs/{job_id}/runs/{run_id}/actions/stop"),
"logs": JobLink("{+api}/jobs/{job_id}/runs/{run_id}/logs"),
}
14 changes: 13 additions & 1 deletion invenio_jobs/services/permissions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2024 CERN.
# Copyright (C) 2024 University of Münster.
#
# Invenio-Jobs is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.
Expand Down Expand Up @@ -30,4 +31,15 @@ class JobPermissionPolicy(BasePermissionPolicy):
can_update = [Administration()]
can_delete = [Administration()]

# TODO: Should run permissions reuse the above or we make a new class?

class RunPermissionPolicy(BasePermissionPolicy):
"""Access control configuration for runs.
Later the runs may be done by librarians.
"""

can_search = [Administration()]
can_create = [Administration()]
can_read = [Administration()]
can_update = [Administration()]
can_delete = [Administration()]
23 changes: 23 additions & 0 deletions invenio_jobs/services/services.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2024 CERN.
# Copyright (C) 2024 University of Münster.
#
# Invenio-Jobs is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.
Expand Down Expand Up @@ -39,3 +40,25 @@ def update(self, identity, id_, data, uow=None):
def delete(self, identity, id_, uow=None):
"""Delete a job."""
raise NotImplementedError()


class RunsService(RecordService):
"""Runs service."""

def search(self, identity, **kwargs):
"""Search for jobs."""
raise NotImplementedError()

def read(self, identity, id_):
"""Retrieve a job."""
raise NotImplementedError()

@unit_of_work()
def update(self, identity, id_, data, uow=None):
"""Update a job."""
raise NotImplementedError()

@unit_of_work()
def delete(self, identity, id_, uow=None):
"""Delete a job."""
raise NotImplementedError()
7 changes: 7 additions & 0 deletions invenio_jobs/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2024 CERN.
# Copyright (C) 2024 University of Münster.
#
# Invenio-Jobs is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.
Expand All @@ -26,3 +27,9 @@ def create_tasks_bp(app):
"""Create tasks blueprint."""
ext = app.extensions["invenio-jobs"]
return ext.tasks_resource.as_blueprint()


def create_runs_bp(app):
"""Create runs blueprint."""
ext = app.extensions["invenio-jobs"]
return ext.runs_resource.as_blueprint()
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ invenio_base.api_apps =
jobs = invenio_jobs:InvenioJobs
invenio_base.api_blueprints =
jobs = invenio_jobs.views:create_jobs_bp
runs = invenio_jobs.views:create_runs_bp
tasks = invenio_jobs.views:create_tasks_bp
invenio_base.finalize_app =
jobs = invenio_jobs.ext:finalize_app
Expand Down

0 comments on commit d225bae

Please sign in to comment.