Skip to content

Commit 94cf520

Browse files
committed
Add a Software Heritage provider
Software Heritage¹ is a non-profit multi-stakeholder initiative which collects, preserves and shares all software that is publicly available in source code form. It provides a public API allowing to retrieve any piece of source code that has been ingested and is identified via its SWHID², including a growing number of jupyter notbooks. Thanks to the recent support for SWHID added in repo2docker, this now bring support to SWHID to binderhub as a Provider. ¹ https://www.softwareheritage.org ² https://docs.softwareheritage.org/devel/swh-model/persistent-identifiers.html#persistent-identifiers
1 parent e192741 commit 94cf520

File tree

8 files changed

+82
-3
lines changed

8 files changed

+82
-3
lines changed

binderhub/app.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
from .repoproviders import (GitHubRepoProvider, GitRepoProvider,
5050
GitLabRepoProvider, GistRepoProvider,
5151
ZenodoProvider, FigshareProvider, HydroshareProvider,
52-
DataverseProvider)
52+
DataverseProvider, SWHIDProvider)
5353
from .metrics import MetricsHandler
5454

5555
from .utils import ByteSpecification, url_path_join
@@ -465,6 +465,7 @@ def _add_slash(self, proposal):
465465
'figshare': FigshareProvider,
466466
'hydroshare': HydroshareProvider,
467467
'dataverse': DataverseProvider,
468+
'swh': SWHIDProvider,
468469
},
469470
config=True,
470471
help="""

binderhub/event-schemas/launch.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"Zenodo",
1515
"Figshare",
1616
"Hydroshare",
17-
"Dataverse"
17+
"Dataverse",
18+
"SWHID"
1819
],
1920
"description": "Provider for the repository being launched"
2021
},

binderhub/main.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"figshare": "Figshare",
2020
"hydroshare": "Hydroshare",
2121
"dataverse": "Dataverse",
22+
"swh": "Software Heritage",
2223
}
2324

2425

binderhub/repoproviders.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,3 +961,41 @@ async def get_resolved_spec(self):
961961

962962
def get_build_slug(self):
963963
return self.gist_id
964+
965+
966+
class SWHIDProvider(RepoProvider):
967+
"""Provide contents of a SWHID record
968+
969+
Users must provide a spec consisting of the SWHID of a directory or revision.
970+
"""
971+
name = Unicode("SWHID")
972+
973+
async def get_resolved_ref(self):
974+
client = AsyncHTTPClient()
975+
req = HTTPRequest("https://archive.softwareheritage.org/api/1/known/",
976+
method="POST",
977+
headers={'content-type': 'application/json'},
978+
body=json.dumps([self.spec]),
979+
user_agent="BinderHub")
980+
r = await client.fetch(req)
981+
r.rethrow()
982+
983+
response = json.loads(r.body)
984+
if response[self.spec]["known"]:
985+
return self.spec
986+
raise RuntimeError(f"Unknown SWHID {self.spec}")
987+
988+
989+
async def get_resolved_spec(self):
990+
return self.spec
991+
992+
def get_repo_url(self):
993+
# While called repo URL, the return value of this function is passed
994+
# as argument to repo2docker, hence we return the spec as is.
995+
return self.spec
996+
997+
async def get_resolved_ref_url(self):
998+
return self.spec
999+
1000+
def get_build_slug(self):
1001+
return "swh-{}".format(self.spec)

binderhub/static/js/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ function getBuildFormValues() {
113113

114114
var ref = $('#ref').val().trim() || $("#ref").attr("placeholder");
115115
if (providerPrefix === 'zenodo' || providerPrefix === 'figshare' || providerPrefix === 'dataverse' ||
116-
providerPrefix === 'hydroshare') {
116+
providerPrefix === 'hydroshare' || providerPrefix === 'swh') {
117117
ref = "";
118118
}
119119
var path = $('#filepath').val().trim();

binderhub/tests/test_repoproviders.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
GitLabRepoProvider,
1313
GitRepoProvider,
1414
HydroshareProvider,
15+
SWHIDProvider,
1516
ZenodoProvider,
1617
strip_suffix,
1718
tokenize_spec,
@@ -490,3 +491,27 @@ def test_gist_secret():
490491

491492
provider = GistRepoProvider(spec=spec, allow_secret_gist=True)
492493
assert IOLoop().run_sync(provider.get_resolved_ref) is not None
494+
495+
496+
@pytest.mark.parametrize('spec,resolved_spec,resolved_ref,resolved_ref_url,build_slug', [
497+
['swh:1:rev:c30614ec4587418fb264efb466cba58991029f16',
498+
'swh:1:rev:c30614ec4587418fb264efb466cba58991029f16',
499+
'swh:1:rev:c30614ec4587418fb264efb466cba58991029f16',
500+
'swh:1:rev:c30614ec4587418fb264efb466cba58991029f16',
501+
'swh-swh:1:rev:c30614ec4587418fb264efb466cba58991029f16'],
502+
])
503+
async def test_swh(spec, resolved_spec, resolved_ref, resolved_ref_url, build_slug):
504+
provider = SWHIDProvider(spec=spec)
505+
506+
# have to resolve the ref first
507+
ref = await provider.get_resolved_ref()
508+
assert ref == resolved_ref
509+
510+
slug = provider.get_build_slug()
511+
assert slug == build_slug
512+
repo_url = provider.get_repo_url()
513+
assert repo_url == spec
514+
ref_url = await provider.get_resolved_ref_url()
515+
assert ref_url == resolved_ref_url
516+
spec = await provider.get_resolved_spec()
517+
assert spec == resolved_spec

doc/developer/repoproviders.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ Currently supported providers, their prefixes and specs are:
3838
+------------+--------------------+-------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
3939
| Git | ``git`` | ``<url-escaped-url>/<commit-sha>`` | A generic repository provider for URLs that point directly to a git repository. |
4040
+------------+--------------------+-------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
41+
| SWHID | ``swh`` | ``<SWHID>`` | A `Software Heritage persistent identifier`_. |
42+
+------------+--------------------+-------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
43+
44+
45+
.. _`Software Heritage persistent identifier`: https://docs.softwareheritage.org/devel/swh-model/persistent-identifiers.html#persistent-identifiers
46+
4147

4248
Adding a new repository provider
4349
================================

doc/reference/repoproviders.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,10 @@ Module: :mod:`binderhub.repoproviders`
7171

7272
.. autoconfigurable:: GitRepoProvider
7373
:members:
74+
75+
76+
:class:`SWHIDProvider`
77+
---------------------------
78+
79+
.. autoconfigurable:: SWHIDProvider
80+
:members:

0 commit comments

Comments
 (0)