def get(self, request, group): """Get the first and last release for a group. This data used to be returned by default in group_details.py, but now that we can collapse it, we're providing this endpoint to fetch the data separately. """ first_release, last_release = get_first_last_release(request, group) data = { "id": str(group.id), "firstRelease": first_release, "lastRelease": last_release, } return Response(data)
def get(self, request: Request, group) -> Response: """ Retrieve an Issue ````````````````` Return details on an individual issue. This returns the basic stats for the issue (title, last seen, first seen), some overall numbers (number of comments, user reports) as well as the summarized event data. :pparam string issue_id: the ID of the issue to retrieve. :auth: required """ from sentry.utils import snuba try: # TODO(dcramer): handle unauthenticated/public response organization = group.project.organization environments = get_environments(request, organization) environment_ids = [e.id for e in environments] expand = request.GET.getlist("expand", []) collapse = request.GET.getlist("collapse", []) # WARNING: the rest of this endpoint relies on this serializer # populating the cache SO don't move this :) data = serialize( group, request.user, GroupSerializerSnuba(environment_ids=environment_ids)) # TODO: these probably should be another endpoint activity = self._get_activity(request, group, num=100) seen_by = self._get_seen_by(request, group) if "release" not in collapse: first_release, last_release = get_first_last_release( request, group) data.update({ "firstRelease": first_release, "lastRelease": last_release, }) get_range = functools.partial(tsdb.get_range, environment_ids=environment_ids) tags = tagstore.get_group_tag_keys(group.project_id, group.id, environment_ids, limit=100) if not environment_ids: user_reports = UserReport.objects.filter(group_id=group.id) else: user_reports = UserReport.objects.filter( group_id=group.id, environment_id__in=environment_ids) now = timezone.now() hourly_stats = tsdb.rollup( get_range(model=tsdb.models.group, keys=[group.id], end=now, start=now - timedelta(days=1)), 3600, )[group.id] daily_stats = tsdb.rollup( get_range( model=tsdb.models.group, keys=[group.id], end=now, start=now - timedelta(days=30), ), 3600 * 24, )[group.id] participants = GroupSubscriptionManager.get_participating_users( group) if "inbox" in expand: inbox_map = get_inbox_details([group]) inbox_reason = inbox_map.get(group.id) data.update({"inbox": inbox_reason}) action_list = self._get_actions(request, group) data.update({ "activity": serialize(activity, request.user), "seenBy": seen_by, "participants": serialize(participants, request.user), "pluginActions": action_list, "pluginIssues": self._get_available_issue_plugins(request, group), "pluginContexts": self._get_context_plugins(request, group), "userReportCount": user_reports.count(), "tags": sorted(serialize(tags, request.user), key=lambda x: x["name"]), "stats": { "24h": hourly_stats, "30d": daily_stats }, }) metrics.incr( "group.update.http_response", sample_rate=1.0, tags={ "status": 200, "detail": "group_details:get:response" }, ) return Response(data) except snuba.RateLimitExceeded: metrics.incr( "group.update.http_response", sample_rate=1.0, tags={ "status": 429, "detail": "group_details:get:snuba.RateLimitExceeded" }, ) raise except Exception: metrics.incr( "group.update.http_response", sample_rate=1.0, tags={ "status": 500, "detail": "group_details:get:Exception" }, ) raise