From f4dd43c7272aee5d85845ae4b963c0d5bf0f68d7 Mon Sep 17 00:00:00 2001 From: Jiri Kyjovsky Date: Sun, 19 Nov 2023 17:21:18 +0100 Subject: [PATCH] WIP --- .../coprs/views/apiv3_ns/apiv3_projects.py | 3 +- .../coprs/views/apiv3_ns/schema/fields.py | 54 ++++++++++-- .../coprs/views/apiv3_ns/schema/schemas.py | 84 ++++++++++++++----- 3 files changed, 112 insertions(+), 29 deletions(-) diff --git a/frontend/coprs_frontend/coprs/views/apiv3_ns/apiv3_projects.py b/frontend/coprs_frontend/coprs/views/apiv3_ns/apiv3_projects.py index 635863a17..f1ac63c72 100644 --- a/frontend/coprs_frontend/coprs/views/apiv3_ns/apiv3_projects.py +++ b/frontend/coprs_frontend/coprs/views/apiv3_ns/apiv3_projects.py @@ -19,6 +19,7 @@ project_edit_input_model, project_fork_input_model, project_delete_input_model, + project_get_input_model, ) from coprs.views.apiv3_ns.schema.docs import fullname_docs, ownername_docs, query_docs from coprs.logic.actions_logic import ActionsLogic @@ -99,7 +100,7 @@ def owner2tuple(ownername): @apiv3_projects_ns.route("/") class Project(Resource): - @apiv3_projects_ns.doc(fullname_docs) + @apiv3_projects_ns.expect(project_get_input_model) @apiv3_projects_ns.marshal_with(project_model) @apiv3_projects_ns.response(HTTPStatus.OK.value, "OK, Project data follows...") @apiv3_projects_ns.response( diff --git a/frontend/coprs_frontend/coprs/views/apiv3_ns/schema/fields.py b/frontend/coprs_frontend/coprs/views/apiv3_ns/schema/fields.py index 7e3fcd863..4a8e3e66d 100644 --- a/frontend/coprs_frontend/coprs/views/apiv3_ns/schema/fields.py +++ b/frontend/coprs_frontend/coprs/views/apiv3_ns/schema/fields.py @@ -3,6 +3,9 @@ # TODO: you can split these fields to some hierarchy e.g. using dataclasses but I # don't see any hierarchy in it +# TODO: Use some shared constants for description - a lot of it is basically copied +# description from forms + # try to be consistent with field names and its corresponding names in API so dynamic creation # of models works @@ -333,14 +336,6 @@ ), ) -source_dict = Raw - -devel_mode = Boolean - -chroot_repos = Raw - -bootstrap = String - with_latest_build = Boolean( description=( "The result will contain 'builds' dictionary with the latest " @@ -356,3 +351,46 @@ ), default=False, ) + +fedora_review = Boolean( + description="Run fedora-review tool for packages in this project" +) + +runtime_dependencies = String( + description=("List of external repositories (== dependencies, specified as baseurls)" + "that will be automatically enabled together with this project repository.") +) + +bootstrap_image = String( + description=("Name of the container image to initialize" + "the bootstrap chroot from. This also implies bootstrap=image." + "This is a noop parameter and its value is ignored.") +) + +name = String(description="Name of the project", example="Copr repository") + +source_dict = Raw( + description="http://python-copr.readthedocs.io/en/latest/client_v3/package_source_types.html" +) + +devel_mode = Boolean(description="If createrepo should run automatically") + +bootstrap = String( + description=("Mock bootstrap feature setup. " + "Possible values are 'default', 'on', 'off', 'image'.") +) + +confirm = Boolean( + description=( + "If forking into a existing project, this needs to be set to True," + "to confirm that user is aware of that." + ) +) + +# TODO: these needs description + +chroot_repos = Raw + +multilib = Boolean + +verify = Boolean diff --git a/frontend/coprs_frontend/coprs/views/apiv3_ns/schema/schemas.py b/frontend/coprs_frontend/coprs/views/apiv3_ns/schema/schemas.py index 29b4de565..c7fa4f77d 100644 --- a/frontend/coprs_frontend/coprs/views/apiv3_ns/schema/schemas.py +++ b/frontend/coprs_frontend/coprs/views/apiv3_ns/schema/schemas.py @@ -2,6 +2,10 @@ # as flask-restx docs suggests if needed +# TODO: in case we will use marshmallow/pydantic, we should share these schemas +# somewhere - CLI, Frontend and backend shares these data with each other + + from abc import ABC from dataclasses import dataclass, fields, asdict, MISSING from typing import Any @@ -10,7 +14,7 @@ from coprs.views.apiv3_ns import api from coprs.views.apiv3_ns.schema import fields as schema_fields -from coprs.views.apiv3_ns.schema.fields import scm_type, mock_chroot +from coprs.views.apiv3_ns.schema.fields import scm_type, mock_chroot, additional_repos @dataclass @@ -65,7 +69,7 @@ class Pagination(Schema): @dataclass -class _ProjectFieldsMixin: +class _ProjectChrootFields: additional_repos: List additional_packages: List additional_modules: List @@ -75,7 +79,7 @@ class _ProjectFieldsMixin: @dataclass -class ProjectChroot(_ProjectFieldsMixin, Schema): +class ProjectChroot(_ProjectChrootFields, Schema): mock_chroot: String ownername: String projectname: String @@ -107,14 +111,14 @@ class Repo(Schema): @dataclass -class ProjectChrootBuildConfig(_ProjectFieldsMixin, Schema): +class ProjectChrootBuildConfig(_ProjectChrootFields, Schema): chroot: String enable_net: Boolean repos: List = List(Nested(_repo_model)) @dataclass -class _SourceDictScmFieldsMixin: +class _SourceDictScmFields: clone_url: String committish: String spec: String @@ -122,7 +126,7 @@ class _SourceDictScmFieldsMixin: @dataclass -class SourceDictScm(_SourceDictScmFieldsMixin, Schema): +class SourceDictScm(_SourceDictScmFields, Schema): source_build_method: String type: String = scm_type @@ -201,7 +205,7 @@ def required_attrs(self) -> list: @dataclass -class PackageAdd(_SourceDictScmFieldsMixin, SourceDictPyPI, InputSchema): +class PackageAdd(_SourceDictScmFields, SourceDictPyPI, InputSchema): # rest of SCM scm_type: String @@ -221,21 +225,14 @@ class PackageAdd(_SourceDictScmFieldsMixin, SourceDictPyPI, InputSchema): @dataclass -class Project(Schema): - id: Integer - name: String - ownername: String - full_name: String +class _ProjectFields: homepage: Url contact: String description: String instructions: String devel_mode: Boolean - persistent: Boolean unlisted_on_hp: Boolean auto_prune: Boolean - chroot_repos: Raw - additional_repos: List enable_net: Boolean bootstrap: String isolation: String @@ -247,16 +244,59 @@ class Project(Schema): @dataclass -class ProjectInput(Project, InputSchema): +class _ProjectGetAddFields: + name: String + persistent: Boolean + additional_repos: List + + +@dataclass +class Project(_ProjectFields, _ProjectGetAddFields, Schema): + id: Integer + ownername: String + full_name: String + chroot_repos: Raw + + +@dataclass +class _ProjectAddEditFields: + chroots: List + bootstrap_image: String + multilib: Boolean + fedora_review: Boolean + runtime_dependencies: String + + +@dataclass +class ProjectAdd(_ProjectFields, _ProjectGetAddFields, _ProjectAddEditFields, InputSchema): ... +@dataclass +class ProjectEdit(_ProjectFields, _ProjectAddEditFields, InputSchema): + # TODO: fix inconsistency - additional_repos <-> repos + repos: String = additional_repos + + +@dataclass +class ProjectFork(InputSchema): + name: String + ownername: String + confirm: Boolean + + +@dataclass +class ProjectDelete(InputSchema): + verify: Boolean + + @dataclass class ProjectGet(InputSchema): - pass + ownername: String + projectname: String -# output models +# OUTPUT MODELS pagination_model = Pagination.get_cls().model() project_chroot_model = ProjectChroot.get_cls().model() repo_model = _repo_model @@ -269,11 +309,15 @@ class ProjectGet(InputSchema): project_model = Project.get_cls().model() -# input models +# INPUT MODELS package_get_input_model = PackageGet.get_cls().input_model() package_add_input_model = PackageAdd.get_cls().input_model() package_edit_input_model = package_add_input_model project_chroot_get_input_model = ProjectChrootGet.get_cls().input_model() -project_add_input_model = None +project_get_input_model = ProjectGet.get_cls().input_model() +project_add_input_model = ProjectAdd.get_cls().input_model() +project_edit_input_model = ProjectEdit.get_cls().input_model() +project_fork_input_model = ProjectFork.get_cls().input_model() +project_delete_input_model = ProjectDelete.get_cls().input_model()