diff --git a/doc/central_scheduler.rst b/doc/central_scheduler.rst index eebc522076..74a19cb3eb 100644 --- a/doc/central_scheduler.rst +++ b/doc/central_scheduler.rst @@ -95,3 +95,14 @@ The task history has the following pages: a listing of all runs of the task ``{name}`` restricted to runs with ``params`` matching the given history. The ``params`` is a json blob describing the parameters, e.g. ``data={"foo": "bar"}`` looks for a task with ``foo=bar``. +* ``/history/by_task_id/{task_id}`` + the latest run of a task given the ``{task_id}``. It is different from just ``{id}`` + and is a derivative of ``params``. It is available via ``{task_id}`` property of a + ``luigi.Task`` instance or via `luigi.task.task_id_str + `_. + This kind of representation is useful for concisely recording URLs in a history tree. + Example screenshot: + + .. figure:: history_by_task_id.png + :alt: By task_id screenshot + diff --git a/doc/history_by_task_id.png b/doc/history_by_task_id.png new file mode 100644 index 0000000000..cd4539cc76 Binary files /dev/null and b/doc/history_by_task_id.png differ diff --git a/luigi/db_task_history.py b/luigi/db_task_history.py index 69dc65d63c..6847c71f6d 100644 --- a/luigi/db_task_history.py +++ b/luigi/db_task_history.py @@ -187,6 +187,13 @@ def find_task_by_id(self, id, session=None): with self._session(session) as session: return session.query(TaskRecord).get(id) + def find_task_by_task_id(self, task_id, session=None): + """ + Find task with the given task ID. + """ + with self._session(session) as session: + return session.query(TaskRecord).filter(TaskRecord.task_id == task_id).all()[-1] + class TaskParameter(Base): # type: ignore """ diff --git a/luigi/server.py b/luigi/server.py index cc6d32a4f6..974e3f2cf8 100644 --- a/luigi/server.py +++ b/luigi/server.py @@ -264,6 +264,13 @@ def get(self, id): self.render("show.html", task=task) +class ByTaskIdHandler(BaseTaskHistoryHandler): + def get(self, task_id): + with self._scheduler.task_history._session(None) as session: + task = self._scheduler.task_history.find_task_by_task_id(task_id, session) + self.render("show.html", task=task) + + class ByParamsHandler(BaseTaskHistoryHandler): def get(self, name): payload = self.get_argument('data', default="{}") @@ -314,6 +321,7 @@ def app(scheduler): (r'/history', RecentRunHandler, {'scheduler': scheduler}), (r'/history/by_name/(.*?)', ByNameHandler, {'scheduler': scheduler}), (r'/history/by_id/(.*?)', ByIdHandler, {'scheduler': scheduler}), + (r'/history/by_task_id/(.*?)', ByTaskIdHandler, {'scheduler': scheduler}), (r'/history/by_params/(.*?)', ByParamsHandler, {'scheduler': scheduler}), (r'/metrics', MetricsHandler, {'scheduler': scheduler}) ]