diff --git a/swh/web/api/views/snapshot.py b/swh/web/api/views/snapshot.py --- a/swh/web/api/views/snapshot.py +++ b/swh/web/api/views/snapshot.py @@ -3,6 +3,10 @@ # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information +from django.http import HttpResponse + +from swh.model.git_objects import snapshot_git_object +from swh.model.model import Snapshot from swh.web.api.apidoc import api_doc, format_docstring from swh.web.api.apiurls import api_route from swh.web.api.utils import enrich_snapshot @@ -102,3 +106,77 @@ ) return response + + +@api_route( + r"/snapshot/(?P[0-9a-f]+)/git", + "api-1-snapshot-git-object", + checksum_args=["snapshot_id"], +) +@api_doc("/snapshot/git") +@format_docstring() +def api_snapshot_git_object(request, snapshot_id): + """ + .. http:get:: /api/1/snapshot/(snapshot_id)/git + + Get the Git object-like data representing a snapshot from the + archive. + + Snapshots are converted to data in the format of a Git object + before being hashed, and this hash is used to identify them. + This endpoint exposes the internal representation (see + :func:`swh.model.git_objects.snapshot_git_object` in our data + model module for details), and so can be used to fetch a binary + blob which hashes to the same identifier. + + :param sha1 snapshot_id: a snapshot identifier + :query str branches_from: optional parameter used to skip branches + whose name is lesser than it before returning them + :query int branches_count: optional parameter used to restrain + the amount of returned branches (default to 1000) + :query str target_types: optional comma separated list parameter + used to filter the target types of branch to return (possible + values that can be contained in that list are ``content``, + ``directory``, ``revision``, ``release``, ``snapshot`` or + ``alias``) + + :resheader Content-Type: application/octet-stream + + :statuscode 200: no error + :statuscode 400: an invalid snapshot identifier has been provided + :statuscode 404: requested snapshot can not be found in the archive + + **Example:** + + .. parsed-literal:: + + :swh_web_api:`snapshot/6a3a2cf0b2b90ce7ae1cf0a221ed68035b686f5a/git` + """ + + snapshot_content_max_size = get_config()["snapshot_content_max_size"] + + branches_from = request.GET.get("branches_from", "") + branches_count = int(request.GET.get("branches_count", snapshot_content_max_size)) + target_types = request.GET.get("target_types", None) + target_types = target_types.split(",") if target_types else None + + data = api_lookup( + archive.lookup_snapshot, + snapshot_id, + branches_from, + branches_count, + target_types, + branch_name_exclude_prefix=None, + notfound_msg="Snapshot with id {} not found.".format(snapshot_id), + enrich_fn=enrich_snapshot, + request=request, + ) + snapshot = Snapshot.from_dict(data) + results = snapshot_git_object(snapshot) + + response = HttpResponse(results, content_type="application/octet-stream") + response["Content-disposition"] = ( + "attachment;filename=snapshot_%s_raw" % snapshot_id + ) + + return response