Refactor how parsed_args are passed to methods

This commit is contained in:
Jake Moshenko 2016-01-26 16:27:36 -05:00
parent daab1b3964
commit 018bf8c5ad
13 changed files with 142 additions and 137 deletions

View file

@ -212,52 +212,55 @@ def query_param(name, help_str, type=reqparse.text_type, default=None,
return func return func
return add_param return add_param
def page_support(page_token_kwarg='page_token', parsed_args_kwarg='parsed_args'):
def inner(func):
""" Adds pagination support to an API endpoint. The decorated API will have an
added query parameter named 'next_page'. Works in tandem with the
modelutil paginate method.
"""
@wraps(func)
@query_param('next_page', 'The page token for the next page', type=str)
def wrapper(self, *args, **kwargs):
page_token = None
def page_support(func): if kwargs[parsed_args_kwarg]['next_page']:
""" Adds pagination support to an API endpoint. The decorated API will have an # Decrypt the page token.
added query parameter named 'next_page'. Works in tandem with the unencrypted = decrypt_string(kwargs[parsed_args_kwarg]['next_page'],
modelutil paginate method. app.config['PAGE_TOKEN_KEY'],
""" ttl=_PAGE_TOKEN_TTL)
@wraps(func) if unencrypted is not None:
@query_param('next_page', 'The page token for the next page', type=str) try:
def wrapper(self, query_args, *args, **kwargs): page_token = json.loads(unencrypted)
page_token = None except ValueError:
pass
if query_args['next_page']: # Note: if page_token is None, we'll receive the first page of results back.
# Decrypt the page token. kwargs[page_token_kwarg] = page_token
unencrypted = decrypt_string(query_args['next_page'], app.config['PAGE_TOKEN_KEY'], (result, next_page_token) = func(self, *args, **kwargs)
ttl=_PAGE_TOKEN_TTL) if next_page_token is not None:
if unencrypted is not None: result['next_page'] = encrypt_string(json.dumps(next_page_token),
try: app.config['PAGE_TOKEN_KEY'])
page_token = json.loads(unencrypted)
except ValueError:
pass
# Note: if page_token is None, we'll receive the first page of results back. return result
(result, next_page_token) = func(self, query_args, page_token=page_token, *args, **kwargs)
if next_page_token is not None:
result['next_page'] = encrypt_string(json.dumps(next_page_token),
app.config['PAGE_TOKEN_KEY'])
return result return wrapper
return inner
return wrapper def parse_args(kwarg_name='parsed_args'):
def inner(func):
@wraps(func)
def wrapper(self, *args, **kwargs):
if '__api_query_params' not in dir(func):
abort(500)
parser = reqparse.RequestParser()
for arg_spec in func.__api_query_params:
parser.add_argument(**arg_spec)
kwargs[kwarg_name] = parser.parse_args()
def parse_args(func): return func(self, *args, **kwargs)
@wraps(func) return wrapper
def wrapper(self, *args, **kwargs): return inner
if '__api_query_params' not in dir(func):
abort(500)
parser = reqparse.RequestParser()
for arg_spec in func.__api_query_params:
parser.add_argument(**arg_spec)
parsed_args = parser.parse_args()
return func(self, parsed_args, *args, **kwargs)
return wrapper
def parse_repository_name(func): def parse_repository_name(func):
@wraps(func) @wraps(func)

View file

@ -185,14 +185,14 @@ class RepositoryBuildList(RepositoryParamResource):
} }
@require_repo_read @require_repo_read
@parse_args @parse_args()
@query_param('limit', 'The maximum number of builds to return', type=int, default=5) @query_param('limit', 'The maximum number of builds to return', type=int, default=5)
@query_param('since', 'Returns all builds since the given unix timecode', type=int, default=None) @query_param('since', 'Returns all builds since the given unix timecode', type=int, default=None)
@nickname('getRepoBuilds') @nickname('getRepoBuilds')
def get(self, args, namespace, repository): def get(self, namespace, repository, parsed_args):
""" Get the list of repository builds. """ """ Get the list of repository builds. """
limit = args.get('limit', 5) limit = parsed_args.get('limit', 5)
since = args.get('since', None) since = parsed_args.get('since', None)
if since is not None: if since is not None:
since = datetime.datetime.utcfromtimestamp(since) since = datetime.datetime.utcfromtimestamp(since)

View file

@ -272,9 +272,9 @@ def swagger_route_data(include_internal=False, compact=False):
@resource('/v1/discovery') @resource('/v1/discovery')
class DiscoveryResource(ApiResource): class DiscoveryResource(ApiResource):
"""Ability to inspect the API for usage information and documentation.""" """Ability to inspect the API for usage information and documentation."""
@parse_args @parse_args()
@query_param('internal', 'Whether to include internal APIs.', type=truthy_bool, default=False) @query_param('internal', 'Whether to include internal APIs.', type=truthy_bool, default=False)
@nickname('discovery') @nickname('discovery')
def get(self, args): def get(self, parsed_args):
""" List all of the API endpoints available in the swagger API format.""" """ List all of the API endpoints available in the swagger API format."""
return swagger_route_data(args['internal']) return swagger_route_data(parsed_args['internal'])

View file

@ -113,19 +113,19 @@ class RepositoryLogs(RepositoryParamResource):
""" Resource for fetching logs for the specific repository. """ """ Resource for fetching logs for the specific repository. """
@require_repo_admin @require_repo_admin
@nickname('listRepoLogs') @nickname('listRepoLogs')
@parse_args @parse_args()
@query_param('starttime', 'Earliest time from which to get logs (%m/%d/%Y %Z)', type=str) @query_param('starttime', 'Earliest time from which to get logs (%m/%d/%Y %Z)', type=str)
@query_param('endtime', 'Latest time to which to get logs (%m/%d/%Y %Z)', type=str) @query_param('endtime', 'Latest time to which to get logs (%m/%d/%Y %Z)', type=str)
@query_param('page', 'The page number for the logs', type=int, default=1) @query_param('page', 'The page number for the logs', type=int, default=1)
@page_support @page_support()
def get(self, args, namespace, repository, page_token): def get(self, namespace, repository, page_token, parsed_args):
""" List the logs for the specified repository. """ """ List the logs for the specified repository. """
repo = model.repository.get_repository(namespace, repository) repo = model.repository.get_repository(namespace, repository)
if not repo: if not repo:
raise NotFound() raise NotFound()
start_time = args['starttime'] start_time = parsed_args['starttime']
end_time = args['endtime'] end_time = parsed_args['endtime']
return get_logs(start_time, end_time, repository=repo, page_token=page_token) return get_logs(start_time, end_time, repository=repo, page_token=page_token)
@ -135,16 +135,16 @@ class UserLogs(ApiResource):
""" Resource for fetching logs for the current user. """ """ Resource for fetching logs for the current user. """
@require_user_admin @require_user_admin
@nickname('listUserLogs') @nickname('listUserLogs')
@parse_args @parse_args()
@query_param('starttime', 'Earliest time from which to get logs. (%m/%d/%Y %Z)', type=str) @query_param('starttime', 'Earliest time from which to get logs. (%m/%d/%Y %Z)', type=str)
@query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str) @query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str)
@query_param('performer', 'Username for which to filter logs.', type=str) @query_param('performer', 'Username for which to filter logs.', type=str)
@page_support @page_support()
def get(self, args, page_token): def get(self, parsed_args, page_token):
""" List the logs for the current user. """ """ List the logs for the current user. """
performer_name = args['performer'] performer_name = parsed_args['performer']
start_time = args['starttime'] start_time = parsed_args['starttime']
end_time = args['endtime'] end_time = parsed_args['endtime']
user = get_authenticated_user() user = get_authenticated_user()
return get_logs(start_time, end_time, performer_name=performer_name, namespace=user.username, return get_logs(start_time, end_time, performer_name=performer_name, namespace=user.username,
@ -157,20 +157,20 @@ class UserLogs(ApiResource):
class OrgLogs(ApiResource): class OrgLogs(ApiResource):
""" Resource for fetching logs for the entire organization. """ """ Resource for fetching logs for the entire organization. """
@nickname('listOrgLogs') @nickname('listOrgLogs')
@parse_args @parse_args()
@query_param('starttime', 'Earliest time from which to get logs. (%m/%d/%Y %Z)', type=str) @query_param('starttime', 'Earliest time from which to get logs. (%m/%d/%Y %Z)', type=str)
@query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str) @query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str)
@query_param('performer', 'Username for which to filter logs.', type=str) @query_param('performer', 'Username for which to filter logs.', type=str)
@query_param('page', 'The page number for the logs', type=int, default=1) @query_param('page', 'The page number for the logs', type=int, default=1)
@page_support @page_support()
@require_scope(scopes.ORG_ADMIN) @require_scope(scopes.ORG_ADMIN)
def get(self, args, orgname, page_token): def get(self, orgname, page_token, parsed_args):
""" List the logs for the specified organization. """ """ List the logs for the specified organization. """
permission = AdministerOrganizationPermission(orgname) permission = AdministerOrganizationPermission(orgname)
if permission.can(): if permission.can():
performer_name = args['performer'] performer_name = parsed_args['performer']
start_time = args['starttime'] start_time = parsed_args['starttime']
end_time = args['endtime'] end_time = parsed_args['endtime']
return get_logs(start_time, end_time, namespace=orgname, performer_name=performer_name, return get_logs(start_time, end_time, namespace=orgname, performer_name=performer_name,
page_token=page_token) page_token=page_token)
@ -184,17 +184,17 @@ class RepositoryAggregateLogs(RepositoryParamResource):
""" Resource for fetching aggregated logs for the specific repository. """ """ Resource for fetching aggregated logs for the specific repository. """
@require_repo_admin @require_repo_admin
@nickname('getAggregateRepoLogs') @nickname('getAggregateRepoLogs')
@parse_args @parse_args()
@query_param('starttime', 'Earliest time from which to get logs (%m/%d/%Y %Z)', type=str) @query_param('starttime', 'Earliest time from which to get logs (%m/%d/%Y %Z)', type=str)
@query_param('endtime', 'Latest time to which to get logs (%m/%d/%Y %Z)', type=str) @query_param('endtime', 'Latest time to which to get logs (%m/%d/%Y %Z)', type=str)
def get(self, args, namespace, repository): def get(self, namespace, repository, parsed_args):
""" Returns the aggregated logs for the specified repository. """ """ Returns the aggregated logs for the specified repository. """
repo = model.repository.get_repository(namespace, repository) repo = model.repository.get_repository(namespace, repository)
if not repo: if not repo:
raise NotFound() raise NotFound()
start_time = args['starttime'] start_time = parsed_args['starttime']
end_time = args['endtime'] end_time = parsed_args['endtime']
return get_aggregate_logs(start_time, end_time, repository=repo) return get_aggregate_logs(start_time, end_time, repository=repo)
@ -204,15 +204,15 @@ class UserAggregateLogs(ApiResource):
""" Resource for fetching aggregated logs for the current user. """ """ Resource for fetching aggregated logs for the current user. """
@require_user_admin @require_user_admin
@nickname('getAggregateUserLogs') @nickname('getAggregateUserLogs')
@parse_args @parse_args()
@query_param('starttime', 'Earliest time from which to get logs. (%m/%d/%Y %Z)', type=str) @query_param('starttime', 'Earliest time from which to get logs. (%m/%d/%Y %Z)', type=str)
@query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str) @query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str)
@query_param('performer', 'Username for which to filter logs.', type=str) @query_param('performer', 'Username for which to filter logs.', type=str)
def get(self, args): def get(self, parsed_args):
""" Returns the aggregated logs for the current user. """ """ Returns the aggregated logs for the current user. """
performer_name = args['performer'] performer_name = parsed_args['performer']
start_time = args['starttime'] start_time = parsed_args['starttime']
end_time = args['endtime'] end_time = parsed_args['endtime']
user = get_authenticated_user() user = get_authenticated_user()
return get_aggregate_logs(start_time, end_time, performer_name=performer_name, return get_aggregate_logs(start_time, end_time, performer_name=performer_name,
@ -225,18 +225,18 @@ class UserAggregateLogs(ApiResource):
class OrgAggregateLogs(ApiResource): class OrgAggregateLogs(ApiResource):
""" Resource for fetching aggregate logs for the entire organization. """ """ Resource for fetching aggregate logs for the entire organization. """
@nickname('getAggregateOrgLogs') @nickname('getAggregateOrgLogs')
@parse_args @parse_args()
@query_param('starttime', 'Earliest time from which to get logs. (%m/%d/%Y %Z)', type=str) @query_param('starttime', 'Earliest time from which to get logs. (%m/%d/%Y %Z)', type=str)
@query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str) @query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str)
@query_param('performer', 'Username for which to filter logs.', type=str) @query_param('performer', 'Username for which to filter logs.', type=str)
@require_scope(scopes.ORG_ADMIN) @require_scope(scopes.ORG_ADMIN)
def get(self, args, orgname): def get(self, orgname, parsed_args):
""" Gets the aggregated logs for the specified organization. """ """ Gets the aggregated logs for the specified organization. """
permission = AdministerOrganizationPermission(orgname) permission = AdministerOrganizationPermission(orgname)
if permission.can(): if permission.can():
performer_name = args['performer'] performer_name = parsed_args['performer']
start_time = args['starttime'] start_time = parsed_args['starttime']
end_time = args['endtime'] end_time = parsed_args['endtime']
return get_aggregate_logs(start_time, end_time, namespace=orgname, return get_aggregate_logs(start_time, end_time, namespace=orgname,
performer_name=performer_name) performer_name=performer_name)

View file

@ -167,7 +167,7 @@ class RepositoryList(ApiResource):
@require_scope(scopes.READ_REPO) @require_scope(scopes.READ_REPO)
@nickname('listRepos') @nickname('listRepos')
@parse_args @parse_args()
@query_param('page', 'Offset page number. (int)', type=int) @query_param('page', 'Offset page number. (int)', type=int)
@query_param('limit', 'Limit on the number of results (int)', type=int) @query_param('limit', 'Limit on the number of results (int)', type=int)
@query_param('namespace', 'Filters the repositories returned to this namespace', type=str) @query_param('namespace', 'Filters the repositories returned to this namespace', type=str)
@ -179,24 +179,26 @@ class RepositoryList(ApiResource):
type=truthy_bool, default=False) type=truthy_bool, default=False)
@query_param('popularity', 'Whether to include the repository\'s popularity metric.', @query_param('popularity', 'Whether to include the repository\'s popularity metric.',
type=truthy_bool, default=False) type=truthy_bool, default=False)
def get(self, args): def get(self, parsed_args):
""" Fetch the list of repositories visible to the current user under a variety of situations. """ Fetch the list of repositories visible to the current user under a variety of situations.
""" """
if not args['namespace'] and not args['starred'] and not args['public']: if not parsed_args['namespace'] and not parsed_args['starred'] and not parsed_args['public']:
raise InvalidRequest('namespace, starred or public are required for this API call') raise InvalidRequest('namespace, starred or public are required for this API call')
repositories, star_lookup = self._load_repositories(args['namespace'], args['public'], repositories, star_lookup = self._load_repositories(parsed_args['namespace'],
args['starred'], args['limit'], parsed_args['public'],
args['page']) parsed_args['starred'],
parsed_args['limit'],
parsed_args['page'])
# Collect the IDs of the repositories found for subequent lookup of popularity # Collect the IDs of the repositories found for subequent lookup of popularity
# and/or last modified. # and/or last modified.
repository_ids = [repo.id for repo in repositories] repository_ids = [repo.id for repo in repositories]
if args['last_modified']: if parsed_args['last_modified']:
last_modified_map = model.repository.get_when_last_modified(repository_ids) last_modified_map = model.repository.get_when_last_modified(repository_ids)
if args['popularity']: if parsed_args['popularity']:
action_count_map = model.repository.get_action_counts(repository_ids) action_count_map = model.repository.get_action_counts(repository_ids)
def repo_view(repo_obj): def repo_view(repo_obj):
@ -209,10 +211,10 @@ class RepositoryList(ApiResource):
repo_id = repo_obj.id repo_id = repo_obj.id
if args['last_modified']: if parsed_args['last_modified']:
repo['last_modified'] = last_modified_map.get(repo_id) repo['last_modified'] = last_modified_map.get(repo_id)
if args['popularity']: if parsed_args['popularity']:
repo['popularity'] = action_count_map.get(repo_id, 0) repo['popularity'] = action_count_map.get(repo_id, 0)
if get_authenticated_user(): if get_authenticated_user():

View file

@ -75,14 +75,14 @@ class UserRobotList(ApiResource):
""" Resource for listing user robots. """ """ Resource for listing user robots. """
@require_user_admin @require_user_admin
@nickname('getUserRobots') @nickname('getUserRobots')
@parse_args @parse_args()
@query_param('permissions', @query_param('permissions',
'Whether to include repostories and teams in which the robots have permission.', 'Whether to include repostories and teams in which the robots have permission.',
type=truthy_bool, default=False) type=truthy_bool, default=False)
def get(self, args): def get(self, parsed_args):
""" List the available robots for the user. """ """ List the available robots for the user. """
user = get_authenticated_user() user = get_authenticated_user()
return robots_list(user.username, include_permissions=args.get('permissions', False)) return robots_list(user.username, include_permissions=parsed_args.get('permissions', False))
@resource('/v1/user/robots/<robot_shortname>') @resource('/v1/user/robots/<robot_shortname>')
@ -124,15 +124,15 @@ class OrgRobotList(ApiResource):
""" Resource for listing an organization's robots. """ """ Resource for listing an organization's robots. """
@require_scope(scopes.ORG_ADMIN) @require_scope(scopes.ORG_ADMIN)
@nickname('getOrgRobots') @nickname('getOrgRobots')
@parse_args @parse_args()
@query_param('permissions', @query_param('permissions',
'Whether to include repostories and teams in which the robots have permission.', 'Whether to include repostories and teams in which the robots have permission.',
type=truthy_bool, default=False) type=truthy_bool, default=False)
def get(self, args, orgname): def get(self, orgname, parsed_args):
""" List the organization's robots. """ """ List the organization's robots. """
permission = OrganizationMemberPermission(orgname) permission = OrganizationMemberPermission(orgname)
if permission.can(): if permission.can():
return robots_list(orgname, include_permissions=args.get('permissions', False)) return robots_list(orgname, include_permissions=parsed_args.get('permissions', False))
raise Unauthorized() raise Unauthorized()

View file

@ -19,18 +19,18 @@ import math
class EntitySearch(ApiResource): class EntitySearch(ApiResource):
""" Resource for searching entities. """ """ Resource for searching entities. """
@path_param('prefix', 'The prefix of the entities being looked up') @path_param('prefix', 'The prefix of the entities being looked up')
@parse_args @parse_args()
@query_param('namespace', 'Namespace to use when querying for org entities.', type=str, @query_param('namespace', 'Namespace to use when querying for org entities.', type=str,
default='') default='')
@query_param('includeTeams', 'Whether to include team names.', type=truthy_bool, default=False) @query_param('includeTeams', 'Whether to include team names.', type=truthy_bool, default=False)
@query_param('includeOrgs', 'Whether to include orgs names.', type=truthy_bool, default=False) @query_param('includeOrgs', 'Whether to include orgs names.', type=truthy_bool, default=False)
@nickname('getMatchingEntities') @nickname('getMatchingEntities')
def get(self, args, prefix): def get(self, prefix, parsed_args):
""" Get a list of entities that match the specified prefix. """ """ Get a list of entities that match the specified prefix. """
teams = [] teams = []
org_data = [] org_data = []
namespace_name = args['namespace'] namespace_name = parsed_args['namespace']
robot_namespace = None robot_namespace = None
organization = None organization = None
@ -42,11 +42,11 @@ class EntitySearch(ApiResource):
if permission.can(): if permission.can():
robot_namespace = namespace_name robot_namespace = namespace_name
if args['includeTeams']: if parsed_args['includeTeams']:
teams = model.team.get_matching_teams(prefix, organization) teams = model.team.get_matching_teams(prefix, organization)
if args['includeOrgs'] and AdministerOrganizationPermission(namespace_name) \ if (parsed_args['includeOrgs'] and AdministerOrganizationPermission(namespace_name) and
and namespace_name.startswith(prefix): namespace_name.startswith(prefix)):
org_data = [{ org_data = [{
'name': namespace_name, 'name': namespace_name,
'kind': 'org', 'kind': 'org',
@ -217,13 +217,13 @@ def conduct_robot_search(username, query, results):
@resource('/v1/find/all') @resource('/v1/find/all')
class ConductSearch(ApiResource): class ConductSearch(ApiResource):
""" Resource for finding users, repositories, teams, etc. """ """ Resource for finding users, repositories, teams, etc. """
@parse_args @parse_args()
@query_param('query', 'The search query.', type=str, default='') @query_param('query', 'The search query.', type=str, default='')
@require_scope(scopes.READ_REPO) @require_scope(scopes.READ_REPO)
@nickname('conductSearch') @nickname('conductSearch')
def get(self, args): def get(self, parsed_args):
""" Get a list of entities and resources that match the specified query. """ """ Get a list of entities and resources that match the specified query. """
query = args['query'] query = parsed_args['query']
if not query: if not query:
return {'results': []} return {'results': []}

View file

@ -62,10 +62,10 @@ class RepositoryImageVulnerabilities(RepositoryParamResource):
@require_repo_read @require_repo_read
@nickname('getRepoImageVulnerabilities') @nickname('getRepoImageVulnerabilities')
@parse_args @parse_args()
@query_param('minimumPriority', 'Minimum vulnerability priority', type=str, @query_param('minimumPriority', 'Minimum vulnerability priority', type=str,
default='Low') default='Low')
def get(self, args, namespace, repository, imageid): def get(self, namespace, repository, imageid, parsed_args):
""" Fetches the vulnerabilities (if any) for a repository tag. """ """ Fetches the vulnerabilities (if any) for a repository tag. """
repo_image = model.image.get_repo_image(namespace, repository, imageid) repo_image = model.image.get_repo_image(namespace, repository, imageid)
if repo_image is None: if repo_image is None:
@ -80,7 +80,7 @@ class RepositoryImageVulnerabilities(RepositoryParamResource):
layer_id = '%s.%s' % (repo_image.docker_image_id, repo_image.storage.uuid) layer_id = '%s.%s' % (repo_image.docker_image_id, repo_image.storage.uuid)
data = _call_security_api('layers/%s/vulnerabilities', layer_id, data = _call_security_api('layers/%s/vulnerabilities', layer_id,
minimumPriority=args.minimumPriority) minimumPriority=parsed_args.minimumPriority)
return { return {
'status': _get_status(repo_image), 'status': _get_status(repo_image),

View file

@ -91,14 +91,14 @@ class SuperUserAggregateLogs(ApiResource):
@require_fresh_login @require_fresh_login
@verify_not_prod @verify_not_prod
@nickname('listAllAggregateLogs') @nickname('listAllAggregateLogs')
@parse_args @parse_args()
@query_param('starttime', 'Earliest time from which to get logs. (%m/%d/%Y %Z)', type=str) @query_param('starttime', 'Earliest time from which to get logs. (%m/%d/%Y %Z)', type=str)
@query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str) @query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str)
def get(self, args): def get(self, parsed_args):
""" Returns the aggregated logs for the current system. """ """ Returns the aggregated logs for the current system. """
if SuperUserPermission().can(): if SuperUserPermission().can():
start_time = args['starttime'] start_time = parsed_args['starttime']
end_time = args['endtime'] end_time = parsed_args['endtime']
return get_aggregate_logs(start_time, end_time) return get_aggregate_logs(start_time, end_time)
@ -113,17 +113,17 @@ class SuperUserLogs(ApiResource):
@require_fresh_login @require_fresh_login
@verify_not_prod @verify_not_prod
@nickname('listAllLogs') @nickname('listAllLogs')
@parse_args @parse_args()
@query_param('starttime', 'Earliest time from which to get logs (%m/%d/%Y %Z)', type=str) @query_param('starttime', 'Earliest time from which to get logs (%m/%d/%Y %Z)', type=str)
@query_param('endtime', 'Latest time to which to get logs (%m/%d/%Y %Z)', type=str) @query_param('endtime', 'Latest time to which to get logs (%m/%d/%Y %Z)', type=str)
@query_param('page', 'The page number for the logs', type=int, default=1) @query_param('page', 'The page number for the logs', type=int, default=1)
@page_support @page_support()
@require_scope(scopes.SUPERUSER) @require_scope(scopes.SUPERUSER)
def get(self, args, page_token): def get(self, parsed_args, page_token):
""" List the usage logs for the current system. """ """ List the usage logs for the current system. """
if SuperUserPermission().can(): if SuperUserPermission().can():
start_time = args['starttime'] start_time = parsed_args['starttime']
end_time = args['endtime'] end_time = parsed_args['endtime']
return get_logs(start_time, end_time, page_token=page_token) return get_logs(start_time, end_time, page_token=page_token)

View file

@ -17,12 +17,12 @@ class ListRepositoryTags(RepositoryParamResource):
""" Resource for listing full repository tag history, alive *and dead*. """ """ Resource for listing full repository tag history, alive *and dead*. """
@require_repo_read @require_repo_read
@parse_args @parse_args()
@query_param('specificTag', 'Filters the tags to the specific tag.', type=str, default='') @query_param('specificTag', 'Filters the tags to the specific tag.', type=str, default='')
@query_param('limit', 'Limit to the number of results to return per page. Max 100.', type=int, default=50) @query_param('limit', 'Limit to the number of results to return per page. Max 100.', type=int, default=50)
@query_param('page', 'Page index for the results. Default 1.', type=int, default=1) @query_param('page', 'Page index for the results. Default 1.', type=int, default=1)
@nickname('listRepoTags') @nickname('listRepoTags')
def get(self, args, namespace, repository): def get(self, namespace, repository, parsed_args):
repo = model.repository.get_repository(namespace, repository) repo = model.repository.get_repository(namespace, repository)
if not repo: if not repo:
raise NotFound() raise NotFound()
@ -42,10 +42,10 @@ class ListRepositoryTags(RepositoryParamResource):
return tag_info return tag_info
specific_tag = args.get('specificTag') or None specific_tag = parsed_args.get('specificTag') or None
page = max(1, args.get('page', 1)) page = max(1, parsed_args.get('page', 1))
limit = min(100, max(1, args.get('limit', 50))) limit = min(100, max(1, parsed_args.get('limit', 50)))
# Note: We ask for limit+1 here, so we can check to see if there are # Note: We ask for limit+1 here, so we can check to see if there are
# additional pages of results. # additional pages of results.
@ -135,10 +135,10 @@ class RepositoryTagImages(RepositoryParamResource):
""" Resource for listing the images in a specific repository tag. """ """ Resource for listing the images in a specific repository tag. """
@require_repo_read @require_repo_read
@nickname('listTagImages') @nickname('listTagImages')
@parse_args @parse_args()
@query_param('owned', 'If specified, only images wholely owned by this tag are returned.', @query_param('owned', 'If specified, only images wholely owned by this tag are returned.',
type=truthy_bool, default=False) type=truthy_bool, default=False)
def get(self, args, namespace, repository, tag): def get(self, namespace, repository, tag, parsed_args):
""" List the images for the specified repository tag. """ """ List the images for the specified repository tag. """
try: try:
tag_image = model.tag.get_tag_image(namespace, repository, tag) tag_image = model.tag.get_tag_image(namespace, repository, tag)
@ -158,7 +158,7 @@ class RepositoryTagImages(RepositoryParamResource):
# Filter the images returned to those not found in the ancestry of any of the other tags in # Filter the images returned to those not found in the ancestry of any of the other tags in
# the repository. # the repository.
if args['owned']: if parsed_args['owned']:
all_tags = model.tag.list_repository_tags(namespace, repository) all_tags = model.tag.list_repository_tags(namespace, repository)
for current_tag in all_tags: for current_tag in all_tags:
if current_tag.name == tag: if current_tag.name == tag:
@ -174,7 +174,7 @@ class RepositoryTagImages(RepositoryParamResource):
return { return {
'images': [image_view(image, image_map_all) for image in all_images 'images': [image_view(image, image_map_all) for image in all_images
if not args['owned'] or (str(image.id) in image_map)] if not parsed_args['owned'] or (str(image.id) in image_map)]
} }

View file

@ -175,11 +175,11 @@ class OrganizationTeam(ApiResource):
class TeamMemberList(ApiResource): class TeamMemberList(ApiResource):
""" Resource for managing the list of members for a team. """ """ Resource for managing the list of members for a team. """
@require_scope(scopes.ORG_ADMIN) @require_scope(scopes.ORG_ADMIN)
@parse_args @parse_args()
@query_param('includePending', 'Whether to include pending members', type=truthy_bool, @query_param('includePending', 'Whether to include pending members', type=truthy_bool,
default=False) default=False)
@nickname('getOrganizationTeamMembers') @nickname('getOrganizationTeamMembers')
def get(self, args, orgname, teamname): def get(self, orgname, teamname, parsed_args):
""" Retrieve the list of members for the specified team. """ """ Retrieve the list of members for the specified team. """
view_permission = ViewTeamPermission(orgname, teamname) view_permission = ViewTeamPermission(orgname, teamname)
edit_permission = AdministerOrganizationPermission(orgname) edit_permission = AdministerOrganizationPermission(orgname)
@ -194,7 +194,7 @@ class TeamMemberList(ApiResource):
members = model.organization.get_organization_team_members(team.id) members = model.organization.get_organization_team_members(team.id)
invites = [] invites = []
if args['includePending'] and edit_permission.can(): if parsed_args['includePending'] and edit_permission.can():
invites = model.team.get_organization_team_member_invites(team.id) invites = model.team.get_organization_team_member_invites(team.id)
data = { data = {

View file

@ -450,12 +450,12 @@ class ActivateBuildTrigger(RepositoryParamResource):
class TriggerBuildList(RepositoryParamResource): class TriggerBuildList(RepositoryParamResource):
""" Resource to represent builds that were activated from the specified trigger. """ """ Resource to represent builds that were activated from the specified trigger. """
@require_repo_admin @require_repo_admin
@parse_args @parse_args()
@query_param('limit', 'The maximum number of builds to return', type=int, default=5) @query_param('limit', 'The maximum number of builds to return', type=int, default=5)
@nickname('listTriggerRecentBuilds') @nickname('listTriggerRecentBuilds')
def get(self, args, namespace, repository, trigger_uuid): def get(self, namespace, repository, trigger_uuid, parsed_args):
""" List the builds started by the specified trigger. """ """ List the builds started by the specified trigger. """
limit = args['limit'] limit = parsed_args['limit']
builds = model.build.list_trigger_builds(namespace, repository, trigger_uuid, limit) builds = model.build.list_trigger_builds(namespace, repository, trigger_uuid, limit)
return { return {
'builds': [build_status_view(bld) for bld in builds] 'builds': [build_status_view(bld) for bld in builds]

View file

@ -691,13 +691,13 @@ class Recovery(ApiResource):
@internal_only @internal_only
class UserNotificationList(ApiResource): class UserNotificationList(ApiResource):
@require_user_admin @require_user_admin
@parse_args @parse_args()
@query_param('page', 'Offset page number. (int)', type=int, default=0) @query_param('page', 'Offset page number. (int)', type=int, default=0)
@query_param('limit', 'Limit on the number of results (int)', type=int, default=5) @query_param('limit', 'Limit on the number of results (int)', type=int, default=5)
@nickname('listUserNotifications') @nickname('listUserNotifications')
def get(self, args): def get(self, parsed_args):
page = args['page'] page = parsed_args['page']
limit = args['limit'] limit = parsed_args['limit']
notifications = list(model.notification.list_notifications(get_authenticated_user(), page=page, notifications = list(model.notification.list_notifications(get_authenticated_user(), page=page,
limit=limit + 1)) limit=limit + 1))
@ -832,14 +832,14 @@ class StarredRepositoryList(ApiResource):
} }
@nickname('listStarredRepos') @nickname('listStarredRepos')
@parse_args @parse_args()
@query_param('page', 'Offset page number. (int)', type=int) @query_param('page', 'Offset page number. (int)', type=int)
@query_param('limit', 'Limit on the number of results (int)', type=int) @query_param('limit', 'Limit on the number of results (int)', type=int)
@require_user_admin @require_user_admin
def get(self, args): def get(self, parsed_args):
""" List all starred repositories. """ """ List all starred repositories. """
page = args['page'] page = parsed_args['page']
limit = args['limit'] limit = parsed_args['limit']
starred_repos = model.repository.get_user_starred_repositories(get_authenticated_user(), starred_repos = model.repository.get_user_starred_repositories(get_authenticated_user(),
page=page, limit=limit) page=page, limit=limit)
def repo_view(repo_obj): def repo_view(repo_obj):