Repository :
http://git.fedorahosted.org/cgit/copr.git
On branch : master
---------------------------------------------------------------
commit 2b35ce82aba874f441d0ff8b5b647bd0ddca61c8
Author: Valentin Gologuzov <vgologuz(a)redhat.com>
Date: Thu Nov 19 17:46:26 2015 +0100
[python] added support for BuildTask and update docs
---------------------------------------------------------------
python/copr/client_v2/client.py | 30 ++-
python/copr/client_v2/common.py | 24 ++
python/copr/client_v2/entities.py | 30 +--
python/copr/client_v2/handlers.py | 71 ++++++-
python/copr/client_v2/resources.py | 236 +++++++++++++++-----
python/copr/client_v2/schemas.py | 16 +-
python/docs/client_v2/general.rst | 5 +-
python/docs/client_v2/handlers.rst | 4 +-
python/docs/client_v2/resource_info/build.rst | 3 +
python/docs/client_v2/resource_info/build_task.rst | 89 ++++++++-
python/docs/client_v2/resource_info/project.rst | 2 +
.../client_v2/resource_info/project_chroot.rst | 3 +
python/docs/client_v2/resources.rst | 10 +
python/docs/conf.py | 6 +-
14 files changed, 423 insertions(+), 106 deletions(-)
diff --git a/python/copr/client_v2/client.py b/python/copr/client_v2/client.py
index db92133..696f98e 100644
--- a/python/copr/client_v2/client.py
+++ b/python/copr/client_v2/client.py
@@ -15,10 +15,8 @@ import six
from six import with_metaclass
from six.moves import configparser
-# from requests_toolbelt.multipart.encoder import MultipartEncoder
-
from .resources import Root
-from .handlers import ProjectHandle, ProjectChrootHandle, BuildHandle, MockChrootHandle
+from .handlers import ProjectHandle, ProjectChrootHandle, BuildHandle, MockChrootHandle,
BuildTaskHandle
from .net_client import NetClient
if sys.version_info < (2, 7):
@@ -58,9 +56,12 @@ class HandlersProvider(object, with_metaclass(ABCMeta)):
"""
pass
- # @abstractproperty
- # def build_tasks(self):
- # pass
+ @abstractproperty
+ def build_tasks(self):
+ """
+ :rtype: BuildTaskHandle
+ """
+ pass
@abstractproperty
def mock_chroots(self):
@@ -94,13 +95,12 @@ class CoprClient(UnicodeMixin, HandlersProvider):
self.no_config = no_config
self._post_init_done = False
- self._main_resources = None
-
self.root = None
self._projects = None
self._project_chroots = None
self._builds = None
+ self._build_tasks = None
self._mock_chroots = None
def _check_client_init(self):
@@ -133,6 +133,14 @@ class CoprClient(UnicodeMixin, HandlersProvider):
return self._builds
@property
+ def build_tasks(self):
+ """
+ :rtype: :py:class:`~copr.client_v2.handlers.BuildTaskHandle`
+ """
+ self._check_client_init()
+ return self._build_tasks
+
+ @property
def mock_chroots(self):
"""
:rtype: :py:class:`~copr.client_v2.handlers.MockChrootHandle`
@@ -236,7 +244,11 @@ class CoprClient(UnicodeMixin, HandlersProvider):
self._builds = BuildHandle(
weakref.proxy(self), self.nc, root_url=self.root_url,
builds_href=self.root.get_href_by_name(u"builds"),)
- # self._build_chroots = BuildTaskHandle()
+
+ self._build_tasks = BuildTaskHandle(
+ weakref.proxy(self), self.nc, root_url=self.root_url,
+ build_tasks_href=self.root.get_href_by_name("build_tasks")
+ )
self._mock_chroots = MockChrootHandle(
weakref.proxy(self), self.nc, root_url=self.root_url,
diff --git a/python/copr/client_v2/common.py b/python/copr/client_v2/common.py
index 615ca6a..2ccd3ec 100644
--- a/python/copr/client_v2/common.py
+++ b/python/copr/client_v2/common.py
@@ -20,3 +20,27 @@ class BuiltPackage(UnicodeMixin):
def __unicode__(self):
return u"{} {}".format(self.name, self.version)
+
+
+class BuildStateValues(object):
+ FAILED = "failed"
+ SUCCEEDED = "succeeded"
+ CANCELED = "canceled"
+ RUNNING = "running"
+ PENDING = "pending"
+ SKIPPED = "skipped"
+ STARTING = "starting"
+ IMPORTING = "importing"
+ UNKNOWN = "unknown"
+
+ALLOWED_BUILD_STATES = {
+ BuildStateValues.FAILED,
+ BuildStateValues.SUCCEEDED,
+ BuildStateValues.CANCELED,
+ BuildStateValues.RUNNING,
+ BuildStateValues.PENDING,
+ BuildStateValues.SKIPPED,
+ BuildStateValues.STARTING,
+ BuildStateValues.IMPORTING,
+ BuildStateValues.UNKNOWN,
+}
diff --git a/python/copr/client_v2/entities.py b/python/copr/client_v2/entities.py
index e62c91e..a4e54ea 100644
--- a/python/copr/client_v2/entities.py
+++ b/python/copr/client_v2/entities.py
@@ -14,24 +14,6 @@ class Link(UnicodeMixin):
@classmethod
def from_dict(cls, data_dict):
- """
- {
- "self": {
- "href":
"/api_2/projects/2482?show_builds=True&show_chroots=True"
- },
- "chroots": {
- "href": "/api_2/projects/2482/chroots"
- },
- "builds": {
- "href": "/api_2/builds?project_id=2482"
- }
- }
-
- return
- {
- <role> -> Link()
- }
- """
return {
role_name:
cls(role_name, definition["href"])
@@ -82,14 +64,16 @@ class BuildEntity(Entity):
return "<Build #{} state: {}>".format(self.id, self.state)
def is_finished(self):
- if self.state in [
+ """
+ Check is the build was finished
+
+ :rtype: bool
+ """
+ return self.state in [
"failed",
"skipped",
"succeeded"
- ]:
- return True
- else:
- return False
+ ]
class BuildTaskEntity(Entity):
diff --git a/python/copr/client_v2/handlers.py b/python/copr/client_v2/handlers.py
index 146772b..b9afddb 100644
--- a/python/copr/client_v2/handlers.py
+++ b/python/copr/client_v2/handlers.py
@@ -6,7 +6,7 @@ import os
from copr.client_v2.net_client import RequestError, MultiPartTuple
from .entities import ProjectChrootEntity
from .resources import Project, OperationResult, ProjectList, ProjectChroot,
ProjectChrootList, Build, BuildList, \
- MockChroot, MockChrootList
+ MockChroot, MockChrootList, BuildTask, BuildTaskList
class AbstractHandle(object):
@@ -200,6 +200,69 @@ class BuildHandle(AbstractHandle):
)
return parts, response
+ def get_build_tasks_handle(self):
+ """
+ :rtype: BuildTasksHandle
+ """
+ return self.client.build_tasks
+
+class BuildTaskHandle(AbstractHandle):
+
+ def __init__(self, client, nc, root_url, build_tasks_href):
+ super(BuildTaskHandle, self).__init__(client, nc, root_url)
+ self.build_tasks_href = build_tasks_href
+ self._base_url = "{}{}".format(self.root_url, build_tasks_href)
+
+ def get_base_url(self):
+ return self._base_url
+
+ def get_list(self, owner=None, project_id=None, build_id=None,
+ state=None, offset=None, limit=None):
+
+ """ Retrieves build tasks list according to the given parameters
+
+ :param str owner: build tasks from the project owner by this user
+ :param int project_id: get tasks only from this project,
+ when used query parameter ``owner`` is ignored
+ :param int build_id: get tasks only from this build,
+ when used query parameters ``owner`` and ``project_id`` are ignored
+ :param str state: get build tasks only with this state, allowed values:
+ ``failed``, ``succeeded``, ``canceled``, ``running``,
+ ``pending``, ``starting``, ``importing``
+ :param int limit: limit number of projects
+ :param int offset: number of projects to skip
+
+ :rtype: :py:class:`~.resources.BuildTaskList`
+ """
+ options = {
+ "owner": owner,
+ "project_id": project_id,
+ "build_id": build_id,
+ "state": state,
+ "limit": limit,
+ "offset": offset
+ }
+
+ response = self.nc.request(self.get_base_url(), query_params=options)
+ return BuildTaskList.from_response(self, response, options)
+
+ def get_one(self, build_id, chroot_name):
+ """ Retrieves single build task object
+
+
+ :param int build_id: id of the build
+ :param str chroot_name: name of the build chroot
+ :rtype: :py:class:`~.resources.BuildTask`
+ """
+
+ url = "{}/{}/{}".format(self.get_base_url(), build_id, chroot_name)
+ response = self.nc.request(url)
+ return BuildTask.from_response(
+ handle=self,
+ response=response,
+ data_dict=response.json,
+ )
+
class ProjectHandle(AbstractHandle):
@@ -283,6 +346,12 @@ class ProjectHandle(AbstractHandle):
"""
return self.client.builds
+ def get_build_tasks_handle(self):
+ """
+ :rtype: BuildTasksHandle
+ """
+ return self.client.build_tasks
+
def get_project_chroots_handle(self):
"""
:rtype: ProjectChrootHandle
diff --git a/python/copr/client_v2/resources.py b/python/copr/client_v2/resources.py
index 0134845..b4abcc4 100644
--- a/python/copr/client_v2/resources.py
+++ b/python/copr/client_v2/resources.py
@@ -5,8 +5,8 @@ from six import with_metaclass
from ..util import UnicodeMixin
-from .entities import Link, ProjectEntity, ProjectChrootEntity, BuildEntity,
MockChrootEntity
-from .schemas import EmptySchema, BuildSchema, ProjectSchema, ProjectChrootSchema,
MockChrootSchema
+from .entities import Link, ProjectEntity, ProjectChrootEntity, BuildEntity,
MockChrootEntity, BuildTaskEntity
+from .schemas import EmptySchema, BuildSchema, ProjectSchema, ProjectChrootSchema,
MockChrootSchema, BuildTaskSchema
class EntityFieldDescriptor(object):
@@ -29,6 +29,20 @@ class EntityFieldDescriptor(object):
setattr(obj._entity, self.name, val)
+class ReadOnlyFieldDescriptor(object):
+ """
+ Entity read-only Field Descriptor
+ """
+ def __init__(self, name):
+ self.name = name
+
+ def __get__(self, obj, objtype):
+ """
+ :type obj: IndividualResource
+ """
+ return getattr(obj._entity, self.name)
+
+
class EntityFieldsMetaClass(type):
"""
Magic: we take fields info from class._schema and attach EntityFieldDescriptor
@@ -39,6 +53,15 @@ class EntityFieldsMetaClass(type):
if schema:
for f_name, f in schema.fields.items():
class_attrs[f_name] = EntityFieldDescriptor(f_name)
+
+ entity_methods = []
+ for base in bases:
+ entity_methods.extend(getattr(base, "_entity_methods", []))
+ entity_methods.extend(class_attrs.get("_entity_methods", []))
+
+ for m_name in entity_methods:
+ class_attrs[m_name] = ReadOnlyFieldDescriptor(m_name)
+
return type.__new__(mcs, class_name, bases, class_attrs)
@@ -51,6 +74,11 @@ class IndividualResource(with_metaclass(EntityFieldsMetaClass,
UnicodeMixin)):
"""
_schema = EmptySchema(strict=True)
+ # todo: this methods only serialize fields which can be modified by the user
+ # think about an apporach to override `load_only=True` fields in
+ # our schemas during the dump function
+ # _entity_methods = ["to_json", "to_dict"]
+
def __init__(self, entity, handle=None, response=None, links=None, embedded=None,
options=None):
self._entity = entity
@@ -65,7 +93,6 @@ class IndividualResource(with_metaclass(EntityFieldsMetaClass,
UnicodeMixin)):
dir(self.__class__) + list(self.__dict__.keys())
))
if self._entity:
- # res.extend([x for x in dir(self._entity) if not
x.startswith("_")])
res.extend(self._schema.fields.keys())
return res
@@ -108,6 +135,7 @@ class Build(IndividualResource):
:type handle: copr.client_v2.handlers.BuildHandle
"""
_schema = BuildSchema(strict=True)
+ _entity_methods = ["is_finished"]
def __init__(self, entity, handle, **kwargs):
super(Build, self).__init__(entity=entity, handle=handle, **kwargs)
@@ -142,6 +170,43 @@ class Build(IndividualResource):
"""
return self._handle.delete(self.id)
+ def get_build_tasks(self, **query_options):
+ """ Get build tasks owned by this build
+
+ :param query_options: see :py:meth:`.handlers.BuildHandle.get_list`
+ :rtype: :py:class:`~.BuildTasksList`
+ """
+ handle = self._handle.get_build_tasks_handle()
+ return handle.get_list(build_id=self.id, **query_options)
+
+
+class BuildTask(IndividualResource):
+ """
+ :type entity: BuildTaskEntity
+ :type handle: copr.client_v2.handlers.BuildTaskHandle
+ """
+ _schema = BuildTaskSchema(strict=True)
+
+ def __init__(self, entity, handle, **kwargs):
+ super(BuildTask, self).__init__(entity=entity, handle=handle, **kwargs)
+ self._entity = entity
+ self._handle = handle
+
+ def get_self(self):
+ """ Retrieves fresh build task object from the service
+
+ :rtype: :py:class:`~.Build`
+ """
+ return self._handle.get_one(self.build_id, self.chroot_name)
+
+
+ @classmethod
+ def from_response(cls, handle, data_dict, response=None, options=None):
+ links = Link.from_dict(data_dict["_links"])
+ entity = BuildTaskEntity.from_dict(data_dict["build_task"])
+ return cls(entity=entity, handle=handle,
+ response=response, links=links, options=options)
+
class Project(IndividualResource):
"""
@@ -188,6 +253,15 @@ class Project(IndividualResource):
handle = self._handle.get_builds_handle()
return handle.get_list(project_id=self.id, **query_options)
+ def get_build_tasks(self, **query_options):
+ """ Get build tasks owned by this project
+
+ :param query_options: see :py:meth:`.handlers.BuildHandle.get_list`
+ :rtype: :py:class:`~.BuildTasksList`
+ """
+ handle = self._handle.get_build_tasks_handle()
+ return handle.get_list(project_id=self.id, **query_options)
+
def get_project_chroot(self, name):
""" Retrieves project chroot object by the given name
@@ -399,6 +473,32 @@ class CollectionResource(Iterable, UnicodeMixin):
raise NotImplementedError
+def _construct_collection(
+ resource_class, handle, response,
+ individuals, options=None, **kwargs):
+
+ """ Helper to avoid code repetition
+
+ :type resource_class: CollectionResource
+ :param handle: AbstractHandle
+ :param response: ResponseWrapper
+ :param options: dict with query options
+ :param individuals: individuals
+
+ :param kwargs: additional parameters for constructor
+
+ :rtype: CollectionResource
+ """
+ return resource_class(
+ handle,
+ response=response,
+ links=Link.from_dict(response.json["_links"]),
+ individuals=individuals,
+ options=options,
+ **kwargs
+ )
+
+
class ProjectList(CollectionResource):
"""
:type handle: copr.client_v2.handlers.ProjectHandle
@@ -423,21 +523,17 @@ class ProjectList(CollectionResource):
@classmethod
def from_response(cls, handle, response, options):
- data_dict = response.json
- result = ProjectList(
- handle,
- response=response,
- links=Link.from_dict(data_dict["_links"]),
- individuals=[
- Project.from_response(
- handle=handle,
- data_dict=dict_part,
- )
- for dict_part in data_dict["projects"]
- ],
- options=options
+ individuals = [
+ Project.from_response(
+ handle=handle,
+ data_dict=dict_part,
+ )
+ for dict_part in response.json["projects"]
+ ]
+ return _construct_collection(
+ cls, handle, response=response,
+ individuals=individuals, options=options
)
- return result
class BuildList(CollectionResource):
@@ -465,21 +561,17 @@ class BuildList(CollectionResource):
@classmethod
def from_response(cls, handle, response, options):
- data_dict = response.json
- result = BuildList(
- handle,
- response=response,
- links=Link.from_dict(data_dict["_links"]),
- individuals=[
- Build.from_response(
- handle=handle,
- data_dict=dict_part,
- )
- for dict_part in data_dict["builds"]
- ],
- options=options
+ individuals = [
+ Build.from_response(
+ handle=handle,
+ data_dict=dict_part,
+ )
+ for dict_part in response.json["builds"]
+ ]
+ return _construct_collection(
+ cls, handle, response=response,
+ individuals=individuals, options=options
)
- return result
class ProjectChrootList(CollectionResource):
@@ -511,20 +603,18 @@ class ProjectChrootList(CollectionResource):
@classmethod
def from_response(cls, handle, response, project):
- data_dict = response.json
- return ProjectChrootList(
- handle,
- project=project,
- response=response,
- links=Link.from_dict(data_dict["_links"]),
- individuals=[
- ProjectChroot.from_response(
- handle=handle,
- data_dict=dict_part,
- project=project
- )
- for dict_part in data_dict["chroots"]
- ]
+ individuals = [
+ ProjectChroot.from_response(
+ handle=handle,
+ data_dict=dict_part,
+ project=project
+ )
+ for dict_part in response.json["chroots"]
+ ]
+
+ return _construct_collection(
+ cls, handle, response=response,
+ individuals=individuals, project=project
)
@@ -548,17 +638,47 @@ class MockChrootList(CollectionResource):
@classmethod
def from_response(cls, handle, response, options):
- data_dict = response.json
- return MockChrootList(
- handle,
- response=response,
- links=Link.from_dict(data_dict["_links"]),
- individuals=[
- MockChroot.from_response(
- handle=handle,
- data_dict=dict_part,
- )
- for dict_part in data_dict["chroots"]
- ],
- options=options
+ individuals = [
+ MockChroot.from_response(
+ handle=handle,
+ data_dict=dict_part,
+ )
+ for dict_part in response.json["chroots"]
+ ]
+ return _construct_collection(
+ cls, handle, response=response,
+ options=options, individuals=individuals
+ )
+
+
+class BuildTaskList(CollectionResource):
+ """
+ List of build tasks
+
+ :type handle: copr.client_v2.handlers.BuildTaskHandle
+ """
+
+ def __init__(self, handle, **kwargs):
+ super(BuildTaskList, self).__init__(**kwargs)
+ self._handle = handle
+
+ @property
+ def build_tasks(self):
+ """
+ :rtype: list of :py:class:`~.resources.BuildTask`
+ """
+ return self._individuals
+
+ @classmethod
+ def from_response(cls, handle, response, options):
+ individuals = [
+ BuildTask.from_response(
+ handle=handle,
+ data_dict=dict_part
+ )
+ for dict_part in response.json["build_tasks"]
+ ]
+ return _construct_collection(
+ cls, handle, response=response,
+ options=options, individuals=individuals
)
diff --git a/python/copr/client_v2/schemas.py b/python/copr/client_v2/schemas.py
index ded42f6..3204cf2 100644
--- a/python/copr/client_v2/schemas.py
+++ b/python/copr/client_v2/schemas.py
@@ -1,12 +1,13 @@
# coding: utf-8
from marshmallow import Schema, fields
+from marshmallow.validate import OneOf
# todo: maybe define schemas for Link sets in each indvidual/collection
# class LinkSchema(Schema):
# href = fields.Str()
#
-from .common import BuiltPackage
+from .common import BuiltPackage, ALLOWED_BUILD_STATES
class EmptySchema(Schema):
@@ -80,14 +81,15 @@ class BuildSchema(Schema):
class BuildTaskSchema(Schema):
- state = fields.Str()
- started_on = fields.Int(load_only=True)
- ended_on = fields.Int(load_only=True)
- git_hash = fields.Str(load_only=True)
+ state = fields.Str(load_only=True, validate=[
+ OneOf(ALLOWED_BUILD_STATES)
+ ])
+ started_on = fields.Int(load_only=True, allow_none=True)
+ ended_on = fields.Int(load_only=True, allow_none=True)
+ git_hash = fields.Str(load_only=True, allow_none=True)
chroot_name = fields.Str(load_only=True)
build_id = fields.Int(load_only=True)
-
- result_dir_url = fields.Str(load_only=True)
+ result_dir_url = fields.Str(load_only=True, allow_none=True)
class MockChrootSchema(Schema):
diff --git a/python/docs/client_v2/general.rst b/python/docs/client_v2/general.rst
index 23d1001..38cda16 100644
--- a/python/docs/client_v2/general.rst
+++ b/python/docs/client_v2/general.rst
@@ -10,7 +10,8 @@ CoprClient
.. autoclass:: copr.client_v2.client.CoprClient
- :members: projects, builds, project_chroots, mock_chroots, create_from_file_config,
create_from_params, post_init
- :undoc-members:
+ :members: projects, builds, build_tasks, project_chroots,
+ mock_chroots, create_from_file_config, create_from_params, post_init
+
diff --git a/python/docs/client_v2/handlers.rst b/python/docs/client_v2/handlers.rst
index 5508c67..e49e289 100644
--- a/python/docs/client_v2/handlers.rst
+++ b/python/docs/client_v2/handlers.rst
@@ -20,8 +20,8 @@ Build
Build task
----------
-.. note::
- Not implemented yet
+.. autoclass:: copr.client_v2.handlers.BuildTaskHandle
+ :members:
Mock chroot
diff --git a/python/docs/client_v2/resource_info/build.rst
b/python/docs/client_v2/resource_info/build.rst
index 04880ee..03f9a05 100644
--- a/python/docs/client_v2/resource_info/build.rst
+++ b/python/docs/client_v2/resource_info/build.rst
@@ -3,6 +3,9 @@
Build
=====
+Build resource allows to submit new builds and access current build progress.
+In fact, build consists of a few tasks, one per chroot, and detailed information is
available through
+:ref:`build-task-info`.
Access to the builds is done through
:py:meth:`~copr.client_v2.client.CoprClient.builds`.
property of initialized :py:class:`~copr.client_v2.client.CoprClient`. That property is
an instance of
diff --git a/python/docs/client_v2/resource_info/build_task.rst
b/python/docs/client_v2/resource_info/build_task.rst
index f17a444..3c2f13f 100644
--- a/python/docs/client_v2/resource_info/build_task.rst
+++ b/python/docs/client_v2/resource_info/build_task.rst
@@ -3,4 +3,91 @@
Build task
==========
-.. note:: Not implement yet
+Build task represents information about individual build tasks. One task is responsible
for one chroot.
+
+Access to the build tasks is done through
:py:meth:`~copr.client_v2.client.CoprClient.build_tasks`.
+property of initialized :py:class:`~copr.client_v2.client.CoprClient`. That property is
an instance of
+:py:class:`~copr.client_v2.handlers.BuildTasksHandle`.
+
+
+It may be more convenient to access build tasks in context of a build
+using method :py:meth:`~copr.client_v2.resources.Build.get_build_tasks`
+of access build tasks in context of a project
+using method :py:meth:`~copr.client_v2.resources.Project.get_build_tasks`
+
+Build tasks are represented by
+:py:class:`~copr.client_v2.resources.BuildTask` class.
+
+.. _build-task-attributes:
+
+Build task entity attributes
+----------------------------
+
+.. copied from frontend docs, don't forget to update
+
+================== ==================== ===============
+Field Type Description
+================== ==================== ===============
+chroot_name str chroot name
+build_id int unique build identifier
+state str current build task state
+started_on int(unixtime UTC) time when the build chroot started
+ended_on int(unixtime UTC) time when the build chroot ended
+git_hash str hash of the git commit in dist-git used for the
build
+result_dir_url str(URL) location of the build results
+================== ==================== ===============
+
+
+.. note::
+ Build Task doesn't currently support any modifications,
+ so all fields are read-only.
+
+
+.. note::
+ all following examples assume that we use ``cl``
+ as an instance of :py:class:`.client_v2.client.CoprClient`,
+ ``p`` as an instance of :py:class:`~copr.client_v2.resources.Project`,
+ ``b`` as an instance of :py:class:`~copr.client_v2.resources.Build`,
+
+
+Get build tasks list
+--------------------
+
+.. sourcecode:: python
+
+ >>> bt_list_1 = cl.build_tasks.get_list(state=BuildStateValues.FAILED,
limit=5)
+ >>> map(str, bt_list_1)
+ ['<Build task #17-fedora-18-x86_64, state: failed>',
+ '<Build task #17-fedora-18-i386, state: failed>',
+ '<Build task #17-fedora-19-x86_64, state: failed>',
+ '<Build task #17-fedora-19-i386, state: failed>',
+ '<Build task #107850-fedora-23-x86_64, state: failed>']
+
+ # using project object
+ >>> bt_list_2 = p.get_build_tasks(limit=5)
+ >>> map(str, bt_list_2)
+ ['<Build task #86705-epel-6-i386, state: succeeded>',
+ '<Build task #86705-epel-6-x86_64, state: failed>',
+ '<Build task #86705-fedora-rawhide-x86_64, state: succeeded>',
+ '<Build task #86705-fedora-rawhide-i386, state: failed>',
+ '<Build task #86705-fedora-20-x86_64, state: succeeded>']
+
+ # using build object
+ >>> bt_list_3 = b.get_build_tasks(limit=5)
+ >>> map(str, bt_list_3)
+ ['<Build task #87165-epel-6-i386, state: failed>',
+ '<Build task #87165-epel-6-x86_64, state: failed>',
+ '<Build task #87165-fedora-rawhide-x86_64, state: succeeded>',
+ '<Build task #87165-fedora-rawhide-i386, state: succeeded>',
+ '<Build task #87165-fedora-20-x86_64, state: succeeded>']
+
+Get single build task
+---------------------
+
+
+.. sourcecode:: python
+
+ >>> bt = cl.build_tasks.get_one(106897, "epel-6-i386")
+ >>> print(bt.state, bt.result_dir_url)
+ (u'succeeded',
u'http://copr-be-dev.cloud.fedoraproject.org/results/rineau/libQGLVie...)
+
diff --git a/python/docs/client_v2/resource_info/project.rst
b/python/docs/client_v2/resource_info/project.rst
index 768d4bd..2d29a2c 100644
--- a/python/docs/client_v2/resource_info/project.rst
+++ b/python/docs/client_v2/resource_info/project.rst
@@ -3,6 +3,8 @@
Project
=======
+Project resource represents copr projects and operations with them.
+
Access to the projects is done through
:py:meth:`~copr.client_v2.client.CoprClient.projects`.
property of initialized :py:class:`~copr.client_v2.client.CoprClient`. That property is
an instance of
:py:class:`~copr.client_v2.handlers.ProjectHandle`. Projects are represented by
diff --git a/python/docs/client_v2/resource_info/project_chroot.rst
b/python/docs/client_v2/resource_info/project_chroot.rst
index ae59c75..7936444 100644
--- a/python/docs/client_v2/resource_info/project_chroot.rst
+++ b/python/docs/client_v2/resource_info/project_chroot.rst
@@ -4,6 +4,9 @@
Project chroot
==============
+Projects Chroots allows to enable and disable target chroots and
+modify project settings dedicated for specific chroots.
+
Access to the project chroots is done through
:py:meth:`~copr.client_v2.client.CoprClient.project_chroots`.
property of initialized :py:class:`~copr.client_v2.client.CoprClient`. That property is
an instance of
:py:class:`~copr.client_v2.handlers.ProjectChrootHandle`.
diff --git a/python/docs/client_v2/resources.rst b/python/docs/client_v2/resources.rst
index 4d00934..e895256 100644
--- a/python/docs/client_v2/resources.rst
+++ b/python/docs/client_v2/resources.rst
@@ -31,6 +31,16 @@ see entity attributes at :ref:`build-attributes`.
.. autoclass:: copr.client_v2.resources.BuildList
:members:
+Build task
+----------
+see entity attributes at :ref:`build-task-attributes`.
+
+.. autoclass:: copr.client_v2.resources.BuildTask
+ :members:
+
+.. autoclass:: copr.client_v2.resources.BuildTaskList
+ :members:
+
Mock chroot
-----------
see entity attributes at :ref:`mock-chroot-attributes`.
diff --git a/python/docs/conf.py b/python/docs/conf.py
index 115f114..069a46d 100644
--- a/python/docs/conf.py
+++ b/python/docs/conf.py
@@ -50,9 +50,9 @@ copyright = u'2014, Valentin Gologuzov'
# built documents.
#
# The short X.Y version.
-version = '1.52'
+version = '1.63'
# The full version, including alpha/beta/rc tags.
-release = '1.52'
+release = '1.63'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -232,7 +232,7 @@ man_pages = [
# dir menu entry, description, category)
texinfo_documents = [
('index', 'python-copr', u'python-copr Documentation',
- u'Valentin Gologuzov', 'python-copr', 'One line description of
project.',
+ u'copr-devel(a)lists.fedorahosted.org', 'python-copr', 'Python
client for the Copr service',
'Miscellaneous'),
]