Skip to content

Commit 22c9b50

Browse files
committed
Server / Python Client: Add support for extension "tier" metadata
* Add support for uploading extension packages specifying the ``tier`` metadata. The ``tier`` metadata can be set as an integer value of ``1``, ``3`` or ``5``. * Support listing extension with the ``tier`` and introdce the ``tier_compare`` parameter, which can be set as ``exact`` or ``lte`` (less than or equal to). By default, the ``tier_compare`` parameter is set to ``lte`` and extensions with their tier less or equal to ``5`` are listed.
1 parent e3f380c commit 22c9b50

File tree

6 files changed

+46
-5
lines changed

6 files changed

+46
-5
lines changed

CHANGES.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@ details, see the commit logs at https://github.com/girder/slicer_package_manager
88
Next Release
99
============
1010

11+
New Features
12+
------------
13+
14+
* Add support for uploading extension packages specifying the ``tier`` metadata. The ``tier``
15+
metadata can be set as an integer value of ``1``, ``3`` or ``5``.
16+
17+
* Support listing extension with the ``tier`` and introdce the ``tier_compare`` parameter, which can
18+
be set as ``exact`` or ``lte`` (less than or equal to).
19+
By default, the ``tier_compare`` parameter is set to ``lte`` and extensions with their tier less or
20+
equal to ``5`` are listed.
21+
1122
0.9.0
1223
=====
1324

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,6 @@ ignore-variadic-names = true
149149

150150
[tool.ruff.per-file-ignores]
151151
"python_client/slicer_package_manager_client/__init__.py" = ["A002"] # Argument `all` is shadowing a python builtin
152+
153+
[tool.ruff.lint.pylint]
154+
max-statements = 60

python_client/slicer_package_manager_client/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ def deleteDraftRelease(self, app_name, revision, coll_id=None):
217217

218218
def uploadExtension(self, filepath, app_name, ext_os, arch, name, repo_type, repo_url,
219219
revision, app_revision, desc='', icon_url='',
220-
category=None, homepage='', screenshots=None, contributors=None,
220+
category=None, tier=None, homepage='', screenshots=None, contributors=None,
221221
dependency=None, coll_id=None, force=False):
222222
"""
223223
Upload an extension by providing a path to the file. It can also be used to update an
@@ -236,6 +236,7 @@ def uploadExtension(self, filepath, app_name, ext_os, arch, name, repo_type, rep
236236
:param desc: The description of the extension
237237
:param icon_url: Url of the extension's logo
238238
:param category: Category of the extension
239+
:param tier: Tier of the extension.
239240
:param homepage: Url of the extension's homepage
240241
:param screenshots: Space-separate list of URLs of screenshots for the extension.
241242
:param contributors: List of contributors of the extension.
@@ -268,6 +269,7 @@ def _displayProgress(*args, **kwargs):
268269
'description': desc,
269270
'icon_url': icon_url,
270271
'category': category,
272+
'tier': tier,
271273
'homepage': homepage,
272274
'screenshots': screenshots,
273275
'contributors': contributors,
@@ -313,6 +315,7 @@ def _displayProgress(*args, **kwargs):
313315
'description': desc,
314316
'icon_url': icon_url,
315317
'category': category,
318+
'tier': tier,
316319
'homepage': homepage,
317320
'screenshots': screenshots,
318321
'contributors': contributors,

python_client/slicer_package_manager_client/cli.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,9 @@ def _cli_deleteDraftRelease(sc: SlicerPackageClient, *args, **kwargs):
417417
@click.option('--category', default=None,
418418
help='Category of the extension',
419419
cls=_AdvancedOption)
420+
@click.option('--tier', default=5,
421+
help='Tier of the extension',
422+
cls=_AdvancedOption)
420423
@click.option('--homepage', default='',
421424
help='Url of the extension homepage',
422425
cls=_AdvancedOption)

slicer_package_manager/api/app.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -434,12 +434,15 @@ def deleteReleaseByIdOrName(self, app_folder, release_id_or_name, progress):
434434
.param('app_revision', 'The revision of the application.', required=False)
435435
.param('baseName', 'The baseName of the extension', required=False)
436436
.param('q', 'The search query.', required=False)
437+
.param('tier', 'Tier of the extension.', required=False, enum=[1, 3, 5])
438+
.param('tier_compare', 'Comparison type for the tier.',
439+
required=False, enum=['exact', 'lte'], default='lte')
437440
.pagingParams(defaultSort='created', defaultSortDir=SortDir.DESCENDING)
438441
.errorResponse(),
439442
)
440443
@access.public(scope=TokenScope.DATA_READ)
441444
def getExtensions(self, app_id, extension_name, release_id, extension_id, os, arch,
442-
app_revision, baseName, q, limit, sort, offset=0):
445+
app_revision, baseName, q, tier, tier_compare, limit, sort, offset=0):
443446
"""
444447
Get a list of extension which is filtered by some optional parameters. If the ``release_id``
445448
provided correspond to the draft release, then you must provide the app_revision to use
@@ -454,6 +457,8 @@ def getExtensions(self, app_id, extension_name, release_id, extension_id, os, ar
454457
:param app_revision: The revision of the application
455458
:param baseName: The baseName of the extension
456459
:param q: Text expected to be found in the extension name or description
460+
:param tier: Tier of the extension.
461+
:param tier_compare: Comparison type for the tier specified as "exact" or "lte" (less than or equal to).
457462
:return: The list of extensions
458463
"""
459464
user = self.getCurrentUser()
@@ -484,6 +489,12 @@ def getExtensions(self, app_id, extension_name, release_id, extension_id, os, ar
484489
{'meta.baseName': {'$regex': escaped_query, '$options': 'i'}},
485490
{'meta.description': {'$regex': escaped_query, '$options': 'i'}},
486491
]
492+
if tier:
493+
if tier_compare == 'lte':
494+
filters['meta.tier'] = {'$lte': tier}
495+
else:
496+
# Provide an exact match base on tier
497+
filters['meta.tier'] = tier
487498
if ObjectId.is_valid(release_id):
488499
release = self._model.load(release_id, user=user, level=AccessType.READ)
489500
if release['name'] == constants.DRAFT_RELEASE_NAME:
@@ -563,7 +574,7 @@ def getExtensions(self, app_id, extension_name, release_id, extension_id, os, ar
563574
.param('category', 'Category under which to place the extension. Subcategories should be '
564575
'delimited by character. If none is passed, will render under '
565576
'the Miscellaneous category..', required=False)
566-
577+
.param('tier', 'Tier of the extension.', required=False, dataType='integer')
567578
.param('homepage', 'The url of the extension homepage.', required=False)
568579
.param('screenshots', 'Space-separate list of URLs of screenshots for the extension.',
569580
required=False)
@@ -579,7 +590,7 @@ def getExtensions(self, app_id, extension_name, release_id, extension_id, os, ar
579590
@access.user(scope=TokenScope.DATA_WRITE)
580591
def createOrUpdateExtension(self, app_id, os, arch, baseName, repository_type, repository_url,
581592
revision, app_revision, description,
582-
icon_url, development_status, category, enabled, homepage,
593+
icon_url, development_status, category, tier, enabled, homepage,
583594
screenshots, contributors, dependency, license):
584595
"""
585596
Create or update an extension item.
@@ -600,6 +611,7 @@ def createOrUpdateExtension(self, app_id, os, arch, baseName, repository_type, r
600611
:param revision: The revision of the extension.
601612
:param app_revision: The revision of the application.
602613
:param description: The description of the extension.
614+
:param tier: Tier of the extension.
603615
:return: The created/updated extension.
604616
"""
605617
creator = self.getCurrentUser()
@@ -645,6 +657,8 @@ def createOrUpdateExtension(self, app_id, os, arch, baseName, repository_type, r
645657
params['development_status'] = development_status
646658
if category:
647659
params['category'] = category
660+
if tier:
661+
params['tier'] = tier
648662
if enabled:
649663
params['enabled'] = enabled
650664
if homepage:

slicer_package_manager/models/extension.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ def validate(self, doc):
9595
'icon_url',
9696
'development_status',
9797
'category',
98+
'tier',
9899
'enabled',
99100
'homepage',
100101
'screenshots',
@@ -107,7 +108,13 @@ def validate(self, doc):
107108
raise ValidationException(msg)
108109
specs = []
109110
for meta in extra_params:
110-
if meta == 'enabled':
111+
if meta == 'tier':
112+
specs.append({
113+
'name': meta,
114+
'type': int,
115+
'exception_msg': f'Extension field "{meta}" must be an integer.',
116+
})
117+
elif meta == 'enabled':
111118
specs.append({
112119
'name': meta,
113120
'type': bool,

0 commit comments

Comments
 (0)