Docs update (#61)

* Improve sphinx documentation

* update faq formatting

* fix setup doc

* fix docs according to the generated htmls
This commit is contained in:
2022-05-05 20:24:24 +03:00
committed by Evgeniy Alekseev
parent 720edc24ba
commit 2dac5a2520
88 changed files with 1850 additions and 1829 deletions

View File

@ -327,7 +327,7 @@ def _set_patch_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
parser = root.add_parser("patch-add", help="add patch set", description="create or update source patches",
epilog="In order to add a patch set for the package you will need to clone "
"the AUR package manually, add required changes (e.g. external patches, "
"edit PKGBUILD) and run command, e.g. `ahriman patch path/to/directory`. "
"edit PKGBUILD) and run command, e.g. ``ahriman patch path/to/directory``. "
"By default it tracks *.patch and *.diff files, but this behavior can be changed "
"by using --track option",
formatter_class=_formatter)

View File

@ -27,6 +27,26 @@ from ahriman.models.result import Result
class Application(ApplicationPackages, ApplicationRepository):
"""
base application class
Examples:
This class groups ``Repository`` methods into specific method which process all supposed actions caused by
underlying action. E.g.::
>>> from ahriman.core.configuration import Configuration
>>> from ahriman.models.package_source import PackageSource
>>>
>>> configuration = Configuration()
>>> application = Application("x86_64", configuration, no_report=False, unsafe=False)
>>> # add packages to build queue
>>> application.add(["ahriman"], PackageSource.AUR, without_dependencies=False)
>>>
>>> # check for updates
>>> updates = application.updates([], no_aur=False, no_local=False, no_manual=False, no_vcs=False, log_fn=print)
>>> # updates for specified packages
>>> application.update(updates)
In case if specific actions or their order are required, the direct access to ``Repository`` must
be used instead.
"""
def _finalize(self, result: Result) -> None:

View File

@ -38,6 +38,13 @@ class Handler:
Attributes:
ALLOW_AUTO_ARCHITECTURE_RUN(bool): (class attribute) allow defining architecture from existing repositories
ALLOW_MULTI_ARCHITECTURE_RUN(bool): (class attribute) allow running with multiple architectures
Examples:
Wrapper for all command line actions, though each derived class implements ``run`` method, it usually must not
be called directly. The recommended way is to call ``execute`` class method, e.g.::
>>> from ahriman.application.handlers import Add
>>> Add.execute(args)
"""
ALLOW_AUTO_ARCHITECTURE_RUN = True

View File

@ -123,7 +123,7 @@ class Setup(Handler):
def configuration_create_devtools(prefix: str, architecture: str, source: Path,
no_multilib: bool, repository: str, paths: RepositoryPaths) -> None:
"""
create configuration for devtools based on `source` configuration
create configuration for devtools based on ``source`` configuration
Args:
prefix(str): command prefix in {prefix}-{architecture}-build

View File

@ -44,6 +44,19 @@ class Lock:
reporter(Client): build status reporter instance
paths(RepositoryPaths): repository paths instance
unsafe(bool): skip user check
Examples:
Instance of this class except for controlling file-based lock is also required for basic applications checks.
The common flow is to create instance in ``with`` block and handle exceptions after all::
>>> from ahriman.core.configuration import Configuration
>>>
>>> configuration = Configuration()
>>> try:
>>> with Lock(args, "x86_64", configuration):
>>> perform_actions()
>>> except Exception as exception:
>>> handle_exceptions(exception)
"""
def __init__(self, args: argparse.Namespace, architecture: str, configuration: Configuration) -> None:

View File

@ -28,7 +28,7 @@ class Pacman:
alpm wrapper
Attributes:
handle(Handle): pyalpm root `Handle`
handle(Handle): pyalpm root ``Handle``
"""
def __init__(self, configuration: Configuration) -> None:

View File

@ -19,7 +19,7 @@
#
import requests
from typing import Any, Dict, List
from typing import Any, Dict, List, Type
from ahriman.core.alpm.pacman import Pacman
from ahriman.core.alpm.remote.remote import Remote
@ -62,8 +62,8 @@ class AUR(Remote):
raise InvalidPackageInfo(error_details)
return [AURPackage.from_json(package) for package in response["results"]]
@staticmethod
def remote_git_url(package_base: str, repository: str) -> str:
@classmethod
def remote_git_url(cls: Type[Remote], package_base: str, repository: str) -> str:
"""
generate remote git url from the package base
@ -76,8 +76,8 @@ class AUR(Remote):
"""
return f"{AUR.DEFAULT_AUR_URL}/{package_base}.git"
@staticmethod
def remote_web_url(package_base: str) -> str:
@classmethod
def remote_web_url(cls: Type[Remote], package_base: str) -> str:
"""
generate remote web url from the package base

View File

@ -19,7 +19,7 @@
#
import requests
from typing import Any, Dict, List
from typing import Any, Dict, List, Type
from ahriman.core.alpm.pacman import Pacman
from ahriman.core.alpm.remote.remote import Remote
@ -60,8 +60,8 @@ class Official(Remote):
raise InvalidPackageInfo("API validation error")
return [AURPackage.from_repo(package) for package in response["results"]]
@staticmethod
def remote_git_url(package_base: str, repository: str) -> str:
@classmethod
def remote_git_url(cls: Type[Remote], package_base: str, repository: str) -> str:
"""
generate remote git url from the package base
@ -76,8 +76,8 @@ class Official(Remote):
return "https://github.com/archlinux/svntogit-packages.git" # hardcoded, ok
return "https://github.com/archlinux/svntogit-community.git"
@staticmethod
def remote_web_url(package_base: str) -> str:
@classmethod
def remote_web_url(cls: Type[Remote], package_base: str) -> str:
"""
generate remote web url from the package base

View File

@ -33,6 +33,19 @@ class Remote:
Attributes:
logger(logging.Logger): class logger
Examples:
These classes are designed to be used without instancing. In order to achieve it several class methods are
provided: ``info``, ``multisearch`` and ``search``. Thus, the basic flow is the following::
>>> from ahriman.core.alpm.remote.aur import AUR
>>> from ahriman.core.alpm.remote.official import Official
>>>
>>> package = AUR.info("ahriman", pacman=pacman)
>>> search_result = Official.multisearch("pacman", "manager", pacman=pacman)
Differnece between ``search`` and ``multisearch`` is that ``search`` passes all arguments to underlying wrapper
directly, whereas ``multisearch`` splits search one by one and finds intersection between search results.
"""
def __init__(self) -> None:
@ -79,8 +92,8 @@ class Remote:
}
return list(packages.values())
@staticmethod
def remote_git_url(package_base: str, repository: str) -> str:
@classmethod
def remote_git_url(cls: Type[Remote], package_base: str, repository: str) -> str:
"""
generate remote git url from the package base
@ -96,8 +109,8 @@ class Remote:
"""
raise NotImplementedError
@staticmethod
def remote_web_url(package_base: str) -> str:
@classmethod
def remote_web_url(cls: Type[Remote], package_base: str) -> str:
"""
generate remote web url from the package base

View File

@ -79,7 +79,7 @@ class Sources:
@staticmethod
def fetch(sources_dir: Path, remote: Optional[RemoteSource]) -> None:
"""
either clone repository or update it to origin/`branch`
either clone repository or update it to origin/``remote.branch``
Args:
sources_dir(Path): local path to fetch

View File

@ -43,6 +43,25 @@ class Configuration(configparser.RawConfigParser):
SYSTEM_CONFIGURATION_PATH(Path): (class attribute) default system configuration path distributed by package
architecture(Optional[str]): repository architecture
path(Optional[Path]): path to root configuration file
Examples:
Configuration class provides additional method in order to handle application configuration. Since this class is
derived from built-in ``configparser.RawConfigParser`` class, the same flow is applicable here. Nevertheless,
it is recommended to use ``from_path`` class method which also calls initialization methods::
>>> from pathlib import Path
>>>
>>> configuration = Configuration.from_path(Path("/etc/ahriman.ini"), "x86_64", quiet=False)
>>> repository_name = configuration.get("repository", "name")
>>> makepkg_flags = configuration.getlist("build", "makepkg_flags")
The configuration instance loaded in this way will contain only sections which are defined for the specified
architecture according to the merge rules. Moreover, the architecture names will be removed from section names.
In order to get current settings, the ``check_loaded`` method can be used. This method will raise an
``InitializeException`` in case if configuration was not yet loaded::
>>> path, architecture = configuration.check_loaded()
"""
DEFAULT_LOG_FORMAT = "[%(levelname)s %(asctime)s] [%(filename)s:%(lineno)d %(funcName)s]: %(message)s"
@ -310,7 +329,7 @@ class Configuration(configparser.RawConfigParser):
def set_option(self, section: str, option: str, value: Optional[str]) -> None:
"""
set option. Unlike default `configparser.RawConfigParser.set` it also creates section if it does not exist
set option. Unlike default ``configparser.RawConfigParser.set`` it also creates section if it does not exist
Args:
section(str): section name

View File

@ -58,7 +58,7 @@ def migrate_package_remotes(connection: Connection, paths: RepositoryPaths) -> N
local_cache = paths.cache_for(package_base)
if local_cache.exists() and not package.is_vcs:
continue # skip packages which are not VCS and with local cache
remote_source = RemoteSource.from_remote(PackageSource.AUR, package_base, "aur")
remote_source = RemoteSource.from_source(PackageSource.AUR, package_base, "aur")
if remote_source is None:
continue # should never happen
insert_remote(package_base, remote_source)

View File

@ -73,7 +73,7 @@ class Operations:
commit(bool, optional): if True commit() will be called on success (Default value = False)
Returns:
T: result of the `query` call
T: result of the ``query`` call
"""
with sqlite3.connect(self.path, detect_types=sqlite3.PARSE_DECLTYPES) as connection:
connection.row_factory = self.factory

View File

@ -36,6 +36,16 @@ from ahriman.core.database.operations.patch_operations import PatchOperations
class SQLite(AuthOperations, BuildOperations, PackageOperations, PatchOperations):
"""
wrapper for sqlite3 database
Examples:
Database wrapper must be used together with migration and SQLite3 setup. In order to perform it there is
``load`` class method::
>>> from ahriman.core.configuration import Configuration
>>>
>>> configuration = Configuration()
>>> database = SQLite.load(configuration)
>>> packages = database.packages_get()
"""
@classmethod

View File

@ -38,6 +38,25 @@ class Report:
architecture(str): repository architecture
configuration(Configuration): configuration instance
logger(logging.Logger): class logger
Examples:
``Report`` classes provide several method in order to operate with the report generation and additional class
method ``load`` which can be used in order to determine right report instance::
>>> from ahriman.core.configuration import Configuration
>>>
>>> configuration = Configuration()
>>> report = Report.load("x86_64", configuration, "email")
The ``generate`` method can be used in order to perform the report itself, whereas ``run`` method handles
exception and raises ``ReportFailed`` instead::
>>> try:
>>> report.generate([], Result())
>>> except Exception as exception:
>>> handle_exceptions(exception)
>>>
>>> report.run([], Result())
"""
def __init__(self, architecture: str, configuration: Configuration) -> None:

View File

@ -29,6 +29,25 @@ from ahriman.models.package import Package
class Repository(Executor, UpdateHandler):
"""
base repository control class
Examples:
This class along with traits provides access to local repository actions, e.g. remove packages, update packages,
sync local repository to remote, generate report, etc::
>>> from ahriman.core.configuration import Configuration
>>> from ahriman.core.database.sqlite import SQLite
>>>
>>> configuration = Configuration()
>>> database = SQLite.load(configuration)
>>> repository = Repository("x86_64", configuration, database, no_report=False, unsafe=False)
>>> known_packages = repository.packages()
>>>
>>> build_result = repository.process_build(known_packages)
>>> built_packages = repository.packages_built()
>>> update_result = repository.process_update(built_packages)
>>>
>>> repository.process_report(["email"], update_result)
>>> repository.process_sync(["s3"], update_result.success)
"""
def load_archives(self, packages: Iterable[Path]) -> List[Package]:

View File

@ -179,7 +179,9 @@ class GPG:
def process_sign_repository(self, path: Path) -> List[Path]:
"""
sign repository if required by configuration
:note: more likely you just want to pass `repository_sign_args` to repo wrapper
Note:
more likely you just want to pass ``repository_sign_args`` to repo wrapper
Args:
path(Path): path to repository database

View File

@ -101,7 +101,7 @@ class Client:
def update(self, base: str, status: BuildStatusEnum) -> None:
"""
update package build status. Unlike `add` it does not update package properties
update package build status. Unlike ``add`` it does not update package properties
Args:
base(str): package base to update

View File

@ -36,7 +36,8 @@ class Watcher:
Attributes:
architecture(str): repository architecture
database(SQLite): database instance
known(Dict[str, Tuple[Package, BuildStatus]]): list of known packages. For the most cases `packages` should be used instead
known(Dict[str, Tuple[Package, BuildStatus]]): list of known packages. For the most cases ``packages`` should
be used instead
logger(logging.Logger): class logger
repository(Repository): repository object
status(BuildStatus): daemon status

View File

@ -239,7 +239,7 @@ class WebClient(Client):
def update(self, base: str, status: BuildStatusEnum) -> None:
"""
update package build status. Unlike `add` it does not update package properties
update package build status. Unlike ``add`` it does not update package properties
Args:
base(str): package base to update

View File

@ -96,6 +96,36 @@ class Tree:
Attributes:
leaves[List[Leaf]): list of tree leaves
Examples:
The most important feature here is to generate tree levels one by one which can be achieved by using class
method::
>>> from ahriman.core.configuration import Configuration
>>> from ahriman.core.database.sqlite import SQLite
>>> from ahriman.core.repository import Repository
>>>
>>> configuration = Configuration()
>>> database = SQLite.load(configuration)
>>> repository = Repository("x86_64", configuration, database, no_report=False, unsafe=False)
>>> packages = repository.packages()
>>>
>>> tree = Tree.load(packages, database)
>>> for tree_level in tree.levels():
>>> for package in tree_level:
>>> print(package.base)
>>> print()
The direct constructor call is also possible but requires tree leaves to be instantioned in advance, e.g.::
>>> leaves = [Leaf.load(package, database) for package in packages]
>>> tree = Tree(leaves)
Using the default ``Leaf()`` method is possible, but not really recommended because it requires from the user to
build the dependency list by himself::
>>> leaf = Leaf(package, dependecies)
>>> tree = Tree([leaf])
"""
def __init__(self, leaves: List[Leaf]) -> None:

View File

@ -38,6 +38,24 @@ class Upload:
architecture(str): repository architecture
configuration(Configuration): configuration instance
logger(logging.Logger): application logger
Examples:
These classes provide the way to upload packages to remote sources as it is described in their implementations.
Basic flow includes class instantiating by using the ``load`` method and then calling the ``run`` method which
wraps any internal exceptions into the ``SyncFailed`` exception::
>>> from ahriman.core.configuration import Configuration
>>>
>>> configuration = Configuration()
>>> upload = Upload.load("x86_64", configuration, "s3")
>>> upload.run(configuration.repository_paths.repository, [])
Or in case if direct access to exception is required, the ``sync`` method can be used::
>>> try:
>>> upload.sync(configuration.repository_paths.repository, [])
>>> except Exception as exception:
>>> handle_exceptions(exception)
"""
def __init__(self, architecture: str, configuration: Configuration) -> None:

View File

@ -55,6 +55,23 @@ def check_output(*args: str, exception: Optional[Exception], cwd: Optional[Path]
Raises:
subprocess.CalledProcessError: if subprocess ended with status code different from 0 and no exception supplied
Examples:
Simply call the function::
>>> check_output("echo", "hello world", exception=None)
The more complicated calls which include result logging and input data are also possible::
>>> import logging
>>>
>>> logger = logging.getLogger()
>>> check_output("python", "-c", "greeting = input('say hello: '); print(); print(greeting)",
>>> exception=None, input_data="hello world", logger=logger)
An additional argument ``exception`` can be supplied in order to override the default exception::
>>> check_output("false", exception=RuntimeError("An exception occurred"))
"""
def log(single: str) -> None:
if logger is not None:
@ -101,6 +118,11 @@ def check_user(paths: RepositoryPaths, unsafe: bool) -> None:
Raises:
UnsafeRun: if root uid differs from current uid and check is enabled
Examples:
Simply run function with arguments::
>>> check_user(paths, unsafe=False)
"""
if not paths.root.exists():
return # no directory found, skip check
@ -136,6 +158,16 @@ def filter_json(source: Dict[str, Any], known_fields: Iterable[str]) -> Dict[str
Returns:
Dict[str, Any]: json object without unknown and empty fields
Examples:
This wrapper is mainly used for the dataclasses, thus the flow must be something like this::
>>> from dataclasses import fields
>>> from ahriman.models.package import Package
>>>
>>> known_fields = [pair.name for pair in fields(Package)]
>>> properties = filter_json(dump, known_fields)
>>> package = Package(**properties)
"""
return {key: value for key, value in source.items() if key in known_fields and value is not None}
@ -164,7 +196,7 @@ def package_like(filename: Path) -> bool:
filename(Path): name of file to check
Returns:
bool: True in case if name contains `.pkg.` and not signature, False otherwise
bool: True in case if name contains ``.pkg.`` and not signature, False otherwise
"""
name = filename.name
return ".pkg." in name and not name.endswith(".sig")
@ -193,7 +225,7 @@ def pretty_size(size: Optional[float], level: int = 0) -> str:
Args:
size(Optional[float]): size to convert
level(int, optional): represents current units, 0 is B, 1 is KiB etc (Default value = 0)
level(int, optional): represents current units, 0 is B, 1 is KiB, etc (Default value = 0)
Returns:
str: pretty printable size as string
@ -226,6 +258,13 @@ def tmpdir() -> Generator[Path, None, None]:
Yields:
Path: path to the created directory
Examples:
This function must be used only inside context manager as decorator states::
>>> with tmpdir() as path:
>>> do_something(path)
>>> raise Exception("Clear me after exception please")
"""
path = Path(tempfile.mkdtemp())
try:
@ -244,6 +283,16 @@ def walk(directory_path: Path) -> Generator[Path, None, None]:
Yields:
Path: all found files in given directory with full path
Examples:
Since the ``pathlib`` module does not provide an alternative to ``os.walk``, this wrapper can be used instead::
>>> from pathlib import Path
>>>
>>> for file_path in walk(Path.cwd()):
>>> print(file_path)
Note, however, that unlike the original method, it does not yield directories.
"""
for element in directory_path.iterdir():
if element.is_dir():

View File

@ -56,6 +56,21 @@ class AURPackage:
provides(List[str]): list of packages which this package provides
license(List[str]): list of package licenses
keywords(List[str]): list of package keywords
Examples:
Mainly this class must be used from class methods instead of default ``__init__``::
>>> package = AURPackage.from_json(metadata) # load package from json dump
>>> # ...or alternatively...
>>> package = AURPackage.from_repo(metadata) # load package from official repository RPC
>>> # properties of the class are built based on ones from AUR RPC, thus additional method is required
>>>
>>>
>>> from ahriman.core.alpm.pacman import Pacman
>>>
>>> pacman = Pacman(configuration)
>>> metadata = pacman.get("pacman")
>>> package = AURPackage.from_pacman(next(metadata)) # load package from pyalpm wrapper
"""
id: int

View File

@ -51,6 +51,25 @@ class Package:
Filled only on load from archive
remote(Optional[RemoteSource]): package remote source if applicable
version(str): package full version
Examples:
Different usages of this class may generate different (incomplete) data, e.g. if instantiating class from json::
>>> package = Package.from_json(dump)
it will contain every data available in the json body. Otherwise, if generate package from local archive::
>>> package = Package.from_archive(local_path, pacman, remote=None)
it will probably miss file descriptions (in case if there are multiple packages which belong to the base).
The specific class load method must be defined based on the source provided. The following methods (mostly) must
be used: ``from_archive``, ``from_aur``, ``from_build``, ``from_official`` for sources
``PackageSource.Archive``, ``PackageSource.AUR``, ``PackageSource.Local`` and ``PackageSource.Repository``
repsectively:
>>> ahriman_package = Package.from_aur("ahriman", pacman)
>>> pacman_package = Package.from_official("pacman", pacman)
"""
base: str
@ -145,7 +164,7 @@ class Package:
Package: package properties
"""
package = AUR.info(name, pacman=pacman)
remote = RemoteSource.from_remote(PackageSource.AUR, package.package_base, package.repository)
remote = RemoteSource.from_source(PackageSource.AUR, package.package_base, package.repository)
return cls(package.package_base, package.version, remote, {package.name: PackageDescription()})
@classmethod
@ -207,7 +226,7 @@ class Package:
Package: package properties
"""
package = OfficialSyncdb.info(name, pacman=pacman) if use_syncdb else Official.info(name, pacman=pacman)
remote = RemoteSource.from_remote(PackageSource.Repository, package.package_base, package.repository)
remote = RemoteSource.from_source(PackageSource.Repository, package.package_base, package.repository)
return cls(package.package_base, package.version, remote, {package.name: PackageDescription()})
@staticmethod

View File

@ -44,6 +44,23 @@ class PackageDescription:
licenses(List[str]): package licenses list
provides(List[str]): list of provided packages
url(Optional[str]): package url
Examples:
Unlike the ``Package`` class, this implementation only holds properties. The recommended way to deal with it is
to read data based on the source type - either json or ``pyalpm.Package`` instance::
>>> description = PackageDescription.from_json(dump)
>>>
>>>
>>> from pathlib import Path
>>> from ahriman.core.alpm.pacman import Pacman
>>> from ahriman.core.configuration import Configuration
>>>
>>> configuration = Configuration()
>>> pacman = Pacman(configuration)
>>> pyalpm_description = next(package for package in pacman.get("pacman"))
>>> description = PackageDescription.from_package(
>>> pyalpm_description, Path("/var/cache/pacman/pkg/pacman-6.0.1-4-x86_64.pkg.tar.zst"))
"""
architecture: Optional[str] = None

View File

@ -38,6 +38,13 @@ class PackageSource(str, Enum):
Local(PackageSource): (class attribute) source is locally stored PKGBUILD
Remote(PackageSource): (class attribute) source is remote (http, ftp etc) link
Repository(PackageSource): (class attribute) source is official repository
Examples:
In case if source is unknown the ``resolve()`` and the source descriptor is available method must be used::
>>> real_source = PackageSource.Auto.resolve("ahriman")
the code above will ensure that the presudo-source ``PackageSource.Auto`` will not be processed later.
"""
Auto = "auto"

View File

@ -81,7 +81,7 @@ class RemoteSource:
return None
@classmethod
def from_remote(cls: Type[RemoteSource], source: PackageSource, package_base: str,
def from_source(cls: Type[RemoteSource], source: PackageSource, package_base: str,
repository: str) -> Optional[RemoteSource]:
"""
generate remote source from the package base

View File

@ -37,6 +37,20 @@ class RepositoryPaths:
Attributes:
root(Path): repository root (i.e. ahriman home)
architecture(str): repository architecture
Examples:
This class can be used in order to access the repository tree structure::
>>> paths = RepositoryPaths(Path("/var/lib/ahriman"), "x86_64")
Additional methods can be used in order to ensure that tree is created::
>>> paths.tree_create()
Access to directories inside can be done by either using properties or specifying the package base::
>>> cache_dir = paths.cache
>>> ahriman_cache_dir = paths.cache_for("ahriman")
"""
root: Path

View File

@ -36,6 +36,28 @@ class User:
username(str): username
password(str): hashed user password with salt
access(UserAccess): user role
Examples:
Simply create user from database data and perform required validation::
>>> password = User.generate_password(24)
>>> user = User("ahriman", password, UserAccess.Write)
Since the password supplied may be plain text, the ``hash_password`` method can be used to hash the password::
>>> user.password = user.hash_password("salt")
Having the user instance and password, it can be validated::
>>> if user.check_credentials(password, "salt"):
>>> print("password is valid")
>>> else:
>>> print("password is invalid")
...and finally access can be verified::
>>> if user.verify_access(UserAccess.Read):
>>> print(f"user {user.username} has read access")
"""
username: str

View File

@ -37,11 +37,11 @@ class AddView(BaseView):
"""
add new package
JSON body must be supplied, the following model is used:
JSON body must be supplied, the following model is used::
>>> {
>>> "packages": "ahriman" # either list of packages or package name as in AUR
>>> }
{
"packages": "ahriman" # either list of packages or package name as in AUR
}
Raises:
HTTPBadRequest: if bad data is supplied

View File

@ -37,11 +37,11 @@ class RemoveView(BaseView):
"""
remove existing packages
JSON body must be supplied, the following model is used:
JSON body must be supplied, the following model is used::
>>> {
>>> "packages": "ahriman", # either list of packages or package name
>>> }
{
"packages": "ahriman", # either list of packages or package name
}
Raises:
HTTPBadRequest: if bad data is supplied

View File

@ -37,11 +37,11 @@ class RequestView(BaseView):
"""
request to add new package
JSON body must be supplied, the following model is used:
JSON body must be supplied, the following model is used::
>>> {
>>> "packages": "ahriman" # either list of packages or package name as in AUR
>>> }
{
"packages": "ahriman" # either list of packages or package name as in AUR
}
Raises:
HTTPBadRequest: if bad data is supplied

View File

@ -41,7 +41,7 @@ class SearchView(BaseView):
"""
search packages in AUR
search string (non empty) must be supplied as `for` parameter
search string (non empty) must be supplied as ``for`` parameter
Returns:
Response: 200 with found package bases and descriptions sorted by base

View File

@ -50,11 +50,11 @@ class AhrimanView(BaseView):
"""
update service status
JSON body must be supplied, the following model is used:
JSON body must be supplied, the following model is used::
>>> {
>>> "status": "unknown", # service status string, must be valid `BuildStatusEnum`
>>> }
{
"status": "unknown", # service status string, must be valid ``BuildStatusEnum``
}
Raises:
HTTPBadRequest: if bad data is supplied

View File

@ -81,13 +81,13 @@ class PackageView(BaseView):
"""
update package build status
JSON body must be supplied, the following model is used:
JSON body must be supplied, the following model is used::
>>> {
>>> "status": "unknown", # package build status string, must be valid `BuildStatusEnum`
>>> "package": {} # package body (use `dataclasses.asdict` to generate one), optional.
>>> # Must be supplied in case if package base is unknown
>>> }
{
"status": "unknown", # package build status string, must be valid ``BuildStatusEnum``
"package": {} # package body (use ``dataclasses.asdict`` to generate one), optional.
# Must be supplied in case if package base is unknown
}
Raises:
HTTPBadRequest: if bad data is supplied

View File

@ -71,12 +71,12 @@ class LoginView(BaseView):
"""
login user to service
either JSON body or form data must be supplied the following fields are required:
either JSON body or form data must be supplied the following fields are required::
>>> {
>>> "username": "username" # username to use for login
>>> "password": "pa55w0rd" # password to use for login
>>> }
{
"username": "username", # username to use for login
"password": "pa55w0rd" # password to use for login
}
Raises:
HTTPFound: on success response