repobee_plug
Module Reference¶
platform¶
Platform API specifications and wrappers.
-
class
repobee_plug.platform.
Issue
(title, body, number=None, created_at=None, author=None, state=None, implementation=None)[source]¶ Wrapper class for an Issue API object.
-
class
repobee_plug.platform.
PlatformAPI
(base_url, token, org_name, user)[source]¶ API base class that all API implementations should inherit from. This class functions similarly to an abstract base class, but with a few key distinctions that affect the inheriting class.
Public methods must override one of the public methods of
_APISpec
. If an inheriting class defines any other public method, anPlatformError
is raised when the class is defined.All public methods in
_APISpec
have a default implementation that simply raise aNotImplementedError
. There is no requirement to implement any of them.
-
assign_members
(team, members, permission=<TeamPermission.PUSH: 'push'>)¶ Assign members to a team.
- Parameters
team (
Team
) – A team to assign members to.members (
List
[str
]) – A list of usernames to assign as members to the team. Usernames that don’t exist are ignored.permission (
TeamPermission
) – The permission to add users with.
- Raises
exceptions.PlatformError – If something goes wrong in communicating with the platform.
- Return type
None
-
assign_repo
(team, repo, permission)¶ Assign a repository to a team, granting any members of the team permission to access the repository according to the specified permission.
- Parameters
team (
Team
) – The team to assign the repository to.repo (
Repo
) – The repository to assign to the team.permission (
TeamPermission
) – The permission granted to the team’s members with respect to accessing the repository.
- Raises
exceptions.PlatformError – If something goes wrong in communicating with the platform.
- Return type
None
-
close_issue
(issue)¶ Close the provided issue.
- Parameters
issue (
Issue
) – The issue to close.- Raises
exceptions.PlatformError – If something goes wrong in communicating with the platform.
- Return type
None
-
create_issue
(title, body, repo, assignees=None)¶ Create an issue in the provided repository.
- Parameters
- Return type
- Returns
The created issue.
- Raises
exceptions.PlatformError – If something goes wrong in communicating with the platform.
-
create_repo
(name, description, private, team=None)¶ Create a repository.
If the repository already exists, it is fetched instead of created. This somewhat unintuitive behavior is to speed up repository creation, as first checking if the repository exists can be a bit inconvenient and/or inefficient depending on the platform.
- Parameters
- Return type
- Returns
The created (or fetched) repository.
- Raises
exceptions.PlatformError – If something goes wrong in communicating with the platform.
-
create_team
(name, members=None, permission=<TeamPermission.PUSH: 'push'>)¶ Create a team on the platform.
- Parameters
name (
str
) – Name of the team.members (
Optional
[List
[str
]]) – A list of usernames to assign as members to this team. Usernames that don’t exist are ignored.permission (
TeamPermission
) – The permission the team should have in regards to repository access.
- Return type
- Returns
The created team.
- Raises
exceptions.PlatformError – If something goes wrong in communicating with the platform, in particular if the team already exists.
-
delete_team
(team)¶ Delete the provided team.
- Parameters
team (
Team
) – The team to delete.- Raises
exceptions.PlatformError – If something goes wrong in communicating with the platform.
- Return type
None
-
extract_repo_name
(repo_url)¶ Extract a repo name from the provided url.
-
get_repo
(repo_name, team_name)¶ Get a single repository.
- Parameters
- Return type
- Returns
The fetched repository.
- Raises
exceptions.PlatformError – If something goes wrong in communicating with the platform, in particular if the repo or team does not exist.
-
get_repo_issues
(repo)¶ Get all issues related to a repo.
- Parameters
repo (
Repo
) – The repo to fetch issues from.- Return type
- Returns
The issues related to the provided repo.
- Raises
exceptions.PlatformError – If something goes wrong in communicating with the platform.
-
get_repo_urls
(assignment_names, org_name=None, team_names=None, insert_auth=False)¶ Get repo urls for all specified repo names in the organization. As checking if every single repo actually exists takes a long time with a typical REST API, this function does not in general guarantee that the urls returned actually correspond to existing repos.
If the
org_name
argument is supplied, urls are computed relative to that organization. If it is not supplied, the target organization is used.If the teams argument is supplied, student repo urls are computed instead of master repo urls.
- Parameters
- Return type
- Returns
a list of urls corresponding to the repo names.
-
get_repos
(repo_urls=None)¶ Get repositories from the platform.
- Parameters
repo_urls (
Optional
[List
[str
]]) – Repository URLs to filter the results by. URLs that do not exist on the platform are ignored. Ifrepo_urls=None
, all repos are fetched.- Return type
- Returns
Repositories matching the filters.
- Raises
exceptions.PlatformError – If something goes wrong in communicating with the platform.
-
get_team_repos
(team)¶ Get all repos related to a team.
- Parameters
team (
Team
) – The team to fetch repos from.- Return type
- Returns
The repos related to the provided team.
- Raises
exceptions.PlatformError – If something goes wrong in communicating with the platform.
-
get_teams
(team_names=None)¶ Get teams from the platform.
- Parameters
team_names (
Optional
[List
[str
]]) – Team names to filter by. Names that do not exist on the platform are ignored. Ifteam_names=None
, all teams are fetched.- Return type
- Returns
Teams matching the filters.
- Raises
exceptions.PlatformError – If something goes wrong in communicating with the platform.
-
insert_auth
(url)¶ Insert authorization token into the provided URL.
- Parameters
url (
str
) – A URL to the platform.- Return type
- Returns
The same url, but with authorization credentials inserted.
- Raises
exceptions.InvalidURL – If the provided URL does not point to anything on the platform.
-
static
verify_settings
(user, org_name, base_url, token, template_org_name=None)¶ Verify the following (to the extent that is possible and makes sense for the specific platform):
Base url is correct
The token has sufficient access privileges
- Target organization (specifiend by
org_name
) exists If template_org_name is supplied, this is also checked to exist.
- Target organization (specifiend by
- User is owner in organization (verify by getting
If template_org_name is supplied, user is also checked to be an owner of it.
organization member list and checking roles)
Should raise an appropriate subclass of
PlatformError
when a problem is encountered.
-
class
repobee_plug.platform.
Repo
(name, description, private, url, implementation)[source]¶ Wrapper class for a Repo API object.
-
class
repobee_plug.platform.
Team
(members, name, id, implementation)[source]¶ Wrapper class for a Team API object.
-
class
repobee_plug.platform.
TeamPermission
(value)[source]¶ Enum specifying team permissions on creating teams. On GitHub, for example, this can be e.g. push or pull.
-
repobee_plug.platform.
check_init_params
(reference_params, compare_params)[source]¶ Check that the compare __init__’s parameters are a subset of the reference class’s version.
-
repobee_plug.platform.
check_parameters
(reference, compare)[source]¶ Check if the parameters match, one by one. Stop at the first diff and raise an exception for that parameter.
An exception is made for __init__, for which the compare may be a subset of the reference in no particular order.
localreps¶
Local representations of API objects.
-
class
repobee_plug.localreps.
StudentRepo
(name, team, url, _path=None)[source]¶ Local representation of a student repo.
-
name
¶ Name of this repository.
-
team
¶ The team this repository belongs to.
-
url
¶ URL to the platform repository.
-
path
¶ Path to the local copy of this repository.
-
exceptions¶
Exceptions for repobee_plug.
-
exception
repobee_plug.exceptions.
APIImplementationError
(*args, **kwargs)[source]¶ Raise when an API is defined incorrectly.
-
exception
repobee_plug.exceptions.
BadCredentials
(msg='', status=None)[source]¶ Raise when credentials are rejected.
-
exception
repobee_plug.exceptions.
FileError
(*args, **kwargs)[source]¶ Raise if something goes wrong with reading from or writing to a file.
-
exception
repobee_plug.exceptions.
HookNameError
(*args, **kwargs)[source]¶ Raise when a public method in a class that inherits from
Plugin
does not have a hook name.
-
exception
repobee_plug.exceptions.
InvalidURL
(msg='', status=None)[source]¶ Error to raise if a URL is provided to the platform API, but it is not a valid URL for the platform.
-
exception
repobee_plug.exceptions.
NotFoundError
(msg='', status=None)[source]¶ An exception raised when a platform API fails to find a resource.
-
exception
repobee_plug.exceptions.
PlatformError
(msg='', status=None)[source]¶ An exception raised when the API responds with an error code.
-
exception
repobee_plug.exceptions.
PlugError
(*args, **kwargs)[source]¶ Base class for all repobee_plug exceptions.
fileutils¶
Utility functions for reading and writing to files.
-
repobee_plug.fileutils.
generate_repo_path
(root, team_name, template_repo_name)[source]¶ Generate a relative path to the student repo.
-
repobee_plug.fileutils.
hash_path
(path)[source]¶ Hash the path with SHA1.
Important
This is not a security function, it’s just to avoid name collisions in.
log¶
Logging functions.
-
repobee_plug.log.
debug
(msg)[source]¶ Equivalent to
log(msg, level=logging.DEBUG)
.- Parameters
msg (
str
) – A message to log.- Return type
None
-
repobee_plug.log.
error
(msg)[source]¶ Equivalent to
log(msg, level=logging.ERROR)
.- Parameters
msg (
str
) – A message to log.- Return type
None
-
repobee_plug.log.
exception
(msg)[source]¶ Log an exception.
- Parameters
msg (
str
) – A message to log.- Return type
None
-
repobee_plug.log.
info
(msg)[source]¶ Equivalent to
log(msg, level=logging.INFO)
.- Parameters
msg (
str
) – A message to log.- Return type
None
name¶
Utility functions relating to RepoBee’s naming conventions.
-
repobee_plug.name.
generate_repo_name
(team_name, assignment_name)[source]¶ Construct a repo name for a team.
-
repobee_plug.name.
generate_repo_names
(team_names, assignment_names)[source]¶ Construct all combinations of generate_repo_name(team_name, assignment_name) for the provided team names and master repo names.
cli¶
-
class
repobee_plug.cli.
Command
[source]¶ Mixin class for use with the Plugin class. Explicitly marks a class as a plugin command.
A plugin command must have a command function defined in the class on the following form:
def command(self) -> Optional[plug.Result]: pass
Note that the type hints are not required, so the callback can be defined like this instead:
def command(self): pass
Example usage:
import repobee_plug as plug class Greeting(plug.Plugin, plug.cli.Command): name = plug.cli.option( short_name="-n", help="your name", required=True ) age = plug.cli.option( converter=int, help="your age", default=30 ) def command(self): print(f"Hello, my name is {self.name} and I am {self.age}")
Note that the file is called
command.py
. We can run this command with RepoBee like so:$ repobee -p command.py greeting -n Alice Hello, my name is Alice and I am 30
If your command requires the platform api, simply add an argument called
api
to thecommand
function.def command(self, api: plug.PlatformAPI): pass
-
class
repobee_plug.cli.
CommandExtension
[source]¶ Mixin class for use with the Plugin class. Marks the extending class as a command extension, that adds options to an existing command.
-
repobee_plug.cli.
category
(name, action_names, help='', description='')[source]¶ Create a category for CLI actions.
-
repobee_plug.cli.
command_extension_settings
(actions, config_section_name=None)[source]¶ Settings for a
CommandExtension
.- Parameters
- Return type
CommandExtensionSettings
- Returns
A wrapper object for settings.
-
repobee_plug.cli.
command_settings
(action=None, category=None, help='', description='', base_parsers=None, config_section_name=None)[source]¶ Create a settings object for a
Command
.Example usage:
import repobee_plug as plug class Ext(plug.Plugin, plug.cli.Command): __settings__ = plug.cli.command_settings( action_name="hello", category=plug.cli.CoreCommand.config, ) def command(self): print("Hello, world!")
This can then be called with:
$ repobee -p ext.py config hello Hello, world!
- Parameters
action (
Union
[str
,Action
,None
]) – The name of this command, or aAction
object that defines both category and action for the command. Defaults to the name of the plugin class.category (
Optional
[Category
]) – The category to place this command in. If not specified, then the command will be top-level (i.e. uncategorized). Ifaction
is anAction
(as opposed to astr
), then this argument is not allowed.help (
str
) – A help section for the command. This appears when listing the help section of the command’s category.description (
str
) – A help section for the command. This appears when listing the help section for the command itself.base_parsers (
Optional
[List
[BaseParser
]]) – A list of base parsers to add to the command.config_section_name (
Optional
[str
]) – The name of the configuration section the command should look for configurable options in. Defaults to the name of the plugin the command is defined in.
- Return type
CommandSettings
- Returns
A settings object used internally by RepoBee.
-
repobee_plug.cli.
flag
(short_name=None, long_name=None, help='', const=True, default=None)[source]¶ Create a command line flag for a
Command
or a :py:class`CommandExtension`. This is simply a convenience wrapper aroundoption()
.A flag is specified on the command line as
--flag
, and causes a constant to be stored. If the flag is omitted, a default value is used instead. The default behavior is that specifying--flag
stores the constantTrue
, and omitting it causes it to default toFalse
. It can also be used to store any other form of constant by specifying theconst
argument. If so, then omitting the flag will cause it to default toNone
instead ofFalse
. Finally, the default value can also be overridden by specifying thedefault
argument.Example:
import repobee_plug as plug class Flags(plug.Plugin, plug.cli.Command): # a normal flag, which toggles between True and False is_great = plug.cli.flag() # a "reverse" flag which defaults to True instead of False not_great = plug.cli.flag(const=False, default=True) # a flag that stores a constant and defaults to None meaning = plug.cli.flag(const=42) # a flag that stores a constant and defaults to another constant approve = plug.cli.flag(const="yes", default="no") def command(self): print("is_great", self.is_great) print("not_great", self.not_great) print("meaning", self.meaning) print("approve", self.approve)
We can then call this command (for example) like so:
$ repobee -p ext.py flags --meaning --not-great is_great False not_great False meaning 42 approve no
- Parameters
short_name (
Optional
[str
]) – The short name of this option. Must start with-
.long_name (
Optional
[str
]) – The long name of this option. Must start with –.help (
str
) – A description of this option that is used in the CLI help section.const (
Any
) – The constant to store.default (
Optional
[Any
]) – The value to default to if the flag is omitted.
- Return type
Option
- Returns
A CLI argument wrapper used internally by RepoBee to create command line argument.
-
repobee_plug.cli.
mutually_exclusive_group
(*, __required__=False, **kwargs)[source]¶ - Parameters
__required__ – Whether or not this mutex group is required.
kwargs – Keyword arguments on the form
name=plug.cli.option()
.
-
repobee_plug.cli.
option
(short_name=None, long_name=None, help='', required=False, default=None, configurable=False, converter=None, argparse_kwargs=None)[source]¶ Create an option for a
Command
or aCommandExtension
.Example usage:
import repobee_plug as plug class Hello(plug.Plugin, plug.cli.Command): name = plug.cli.option(help="Your name.") age = plug.cli.option(converter=int, help="Your age.") def command(self): print( f"Hello, my name is {self.name} " f"and I am {self.age} years old" )
This command can then be called like so:
$ repobee -p ext.py hello --name Alice --age 22 Hello, my name is Alice and I am 22 years old
- Parameters
short_name (
Optional
[str
]) – The short name of this option. Must start with-
.long_name (
Optional
[str
]) – The long name of this option. Must start with –.help (
str
) – A description of this option that is used in the CLI help section.required (
bool
) – Whether or not this option is required.configurable (
bool
) – Whether or not this option is configurable. If an option is both configurable and required, having a value for the option in the configuration file makes the option non-required.converter (
Optional
[Callable
[[str
],Any
]]) – A converter function that takes a string and returns the argument in its proper state. Should also perform input validation and raise an error if the input is malformed.argparse_kwargs (
Optional
[Mapping
[str
,Any
]]) – Keyword arguments that are passed directly toargparse.ArgumentParser.add_argument()
- Return type
Option
- Returns
A CLI argument wrapper used internally by RepoBee to create command line arguments.
-
repobee_plug.cli.
positional
(help='', converter=None, argparse_kwargs=None)[source]¶ Create a positional argument for a
Command
or aCommandExtension
.Example usage:
import repobee_plug as plug class Hello(plug.Plugin, plug.cli.Command): name = plug.cli.positional(help="Your name.") age = plug.cli.positional(converter=int, help="Your age.") def command(self): print( f"Hello, my name is {self.name} " f"and I am {self.age} years old" )
This command can then be called like so:
$ repobee -p ext.py hello Alice 22 Hello, my name is Alice and I am 22 years old
- Parameters
help (
str
) – The help section for the positional argument.converter (
Optional
[Callable
[[str
],Any
]]) – A converter function that takes a string and returns the argument in its proper state. Should also perform input validation and raise an error if the input is malformed.argparse_kwargs (
Optional
[Mapping
[str
,Any
]]) – Keyword arguments that are passed directly toargparse.ArgumentParser.add_argument()
- Return type
Option
- Returns
A CLI argument wrapper used internally by RepoBee to create command line argument.
_corehooks¶
Important
The
_corehooks
module is part of the module reference only for specification purposes. Plugin developers should never try to import from this module.
Hookspecs for repobee core hooks.
Core hooks provide the basic functionality of repobee. These hooks all have default implementations, but are overridden by any other implementation. All hooks in this module should have the firstresult=True option to the hookspec to allow for this dynamic override.
-
class
repobee_plug._corehooks.
APIHook
[source]¶ Hooks related to platform APIs.
-
class
repobee_plug._corehooks.
PeerReviewHook
[source]¶ Hook functions related to allocating peer reviews.
-
generate_review_allocations
(teams, num_reviews)[source]¶ Generate
ReviewAllocation
tuples from the provided teams, given that this concerns reviews for a single master repo.The provided teams of students should be treated as units. That is to say, if there are multiple members in a team, they should always be assigned to the same review team. The best way to merge two teams
team_a
andteam_b
into one review team is to simply do:team_c = plug.StudentTeam(members=team_a.members + team_b.members)
This can be scaled to however many teams you would like to merge. As a practical example, if teams
team_a
andteam_b
are to reviewteam_c
, then the followingReviewAllocation
tuple, here calledallocation
, should be contained in the returned list.review_team = plug.StudentTeam( members=team_a.members + team_b.members ) allocation = containers.ReviewAllocation( review_team=review_team, reviewed_team=team_c, )
Note
Respecting the
num_reviews
argument is optional: only do it if it makes sense. It’s good practice to issue a warning if num_reviews is ignored, however.
-
_exthooks¶
Important
The
_exthooks
module is part of the module reference only for specification purposes. Plugin developers should never try to import from this module.
Hookspecs for repobee extension hooks.
Extension hooks add something to the functionality of repobee, but are not necessary for its operation. Currently, all extension hooks are related to cloning repos.
-
class
repobee_plug._exthooks.
CloneHook
[source]¶ Hook functions related to cloning repos.
-
clone_parser_hook
(clone_parser)[source]¶ Do something with the clone repos subparser before it is used used to parse CLI options. The typical task is to add options to it.
Danger
This hook no longer has any effect, it is only kept for testing purposes.
Deprecated since version 0.12.0: This hook is has been replaced by
CloneHook.handle_parsed_args()
andCloneHook.handle_processed_args()
. Once all known, existing plugins have been migrated to the new hook, this hook will be removed.- Parameters
clone_parser (
ArgumentParser
) – Theclone
subparser.- Return type
None
-
config_hook
(config_parser)[source]¶ Hook into the config file parsing.
- Parameters
config – the config parser after config has been read.
- Return type
None
-
handle_parsed_args
(args)[source]¶ Handle the parsed args from the parser, before any processing is applied.
- Parameters
args (
Namespace
) – The full namespace returned byargparse.ArgumentParser.parse_args()
- Return type
None
-
handle_processed_args
(args)[source]¶ Handle the parsed command line arguments after RepoBee has applied processing.
- Parameters
args (
Namespace
) – A processed version of the parsed CLI arguments.- Return type
None
-
post_clone
(repo, api)[source]¶ Operate on a student repository after it has been cloned.
- Parameters
repo (
StudentRepo
) – A local representation of a student repo. Thepath
attribute is always set to a valid directory containing the repo.api (
PlatformAPI
) – An instance of the platform API.
- Return type
Optional
[Result
]- Returns
Optionally returns a Result for reporting the outcome of the hook. May also return None, in which case no reporting will be performed for the hook.
-
-
class
repobee_plug._exthooks.
SetupHook
[source]¶ Hook functions related to setting up repos.
-
pre_setup
(repo, api)[source]¶ Operate on a template repository before it is distributed to students.
Note
Structural changes to the master repo are not currently supported. Changes to the repository during the callback will not be reflected in the generated repositories. Support for preprocessing is not planned as it is technically difficult to implement.
- Parameters
repo (
TemplateRepo
) – Representation of a local template repo.api (
PlatformAPI
) – An instance of the platform API.
- Return type
Optional
[Result
]- Returns
Optionally returns a Result for reporting the outcome of the hook. May also return None, in which case no reporting will be performed for the hook.
-