prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Search related events by event ID
  
  ![image](https://user-images.githubusercontent.com/2153/29005586-1dfdfbf6-7a93-11e7-9127-c82c0356b4c6.png)
  
  Right now you can search [by message or tags](https://github.com/getsentry/sentry/blob/master/src/sentry/api/endpoints/group_events.py#L104), but not individual event ID. This is useful when trying to locate a specific event. More useful now that sampling has been disabled by default.
  
  We should also add a column for event ID here.
  
  Refs #3147
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `src/sentry/api/endpoints/group_events.py`
  Content:
  ```
  1 from __future__ import absolute_import
  2 
  3 import six
  4 
  5 from sentry import tagstore
  6 from sentry.api.base import DocSection, EnvironmentMixin
  7 from sentry.api.bases import GroupEndpoint
  8 from sentry.api.serializers import serialize
  9 from sentry.api.paginator import DateTimePaginator
  10 from sentry.models import Environment, Event, Group
  11 from sentry.search.utils import parse_query
  12 from sentry.utils.apidocs import scenario, attach_scenarios
  13 from rest_framework.response import Response
  14 from sentry.search.utils import InvalidQuery
  15 
  16 
  17 @scenario('ListAvailableSamples')
  18 def list_available_samples_scenario(runner):
  19     group = Group.objects.filter(project=runner.default_project).first()
  20     runner.request(method='GET', path='/issues/%s/events/' % group.id)
  21 
  22 
  23 class GroupEventsEndpoint(GroupEndpoint, EnvironmentMixin):
  24     doc_section = DocSection.EVENTS
  25 
  26     @attach_scenarios([list_available_samples_scenario])
  27     def get(self, request, group):
  28         """
  29         List an Issue's Events
  30         ``````````````````````
  31 
  32         This endpoint lists an issue's events.
  33 
  34         :pparam string issue_id: the ID of the issue to retrieve.
  35         :auth: required
  36         """
  37 
  38         events = Event.objects.filter(
  39             group_id=group.id,
  40         )
  41 
  42         query = request.GET.get('query')
  43         if query:
  44             try:
  45                 query_kwargs = parse_query(group.project, query, request.user)
  46             except InvalidQuery as exc:
  47                 return Response({'detail': six.text_type(exc)}, status=400)
  48 
  49             if query_kwargs['query']:
  50                 events = events.filter(
  51                     message__icontains=query_kwargs['query'],
  52                 )
  53 
  54             if query_kwargs['tags']:
  55                 try:
  56                     environment_id = self._get_environment_id_from_request(
  57                         request, group.project.organization_id)
  58                 except Environment.DoesNotExist:
  59                     event_ids = []
  60                 else:
  61                     event_ids = tagstore.get_group_event_ids(
  62                         group.project_id, group.id, environment_id, query_kwargs['tags'])
  63 
  64                 if event_ids:
  65                     events = events.filter(
  66                         id__in=event_ids,
  67                     )
  68                 else:
  69                     events = events.none()
  70 
  71         return self.paginate(
  72             request=request,
  73             queryset=events,
  74             order_by='-datetime',
  75             on_results=lambda x: serialize(x, request.user),
  76             paginator_cls=DateTimePaginator,
  77         )
  78
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/src/sentry/api/endpoints/group_events.py b/src/sentry/api/endpoints/group_events.py
  --- a/src/sentry/api/endpoints/group_events.py
  +++ b/src/sentry/api/endpoints/group_events.py
  @@ -12,6 +12,7 @@
   from sentry.utils.apidocs import scenario, attach_scenarios
   from rest_framework.response import Response
   from sentry.search.utils import InvalidQuery
  +from django.db.models import Q
   
   
   @scenario('ListAvailableSamples')
  @@ -40,6 +41,7 @@
           )
   
           query = request.GET.get('query')
  +
           if query:
               try:
                   query_kwargs = parse_query(group.project, query, request.user)
  @@ -47,9 +49,12 @@
                   return Response({'detail': six.text_type(exc)}, status=400)
   
               if query_kwargs['query']:
  -                events = events.filter(
  -                    message__icontains=query_kwargs['query'],
  -                )
  +                q = Q(message__icontains=query_kwargs['query'])
  +
  +                if len(query) == 32:
  +                    q |= Q(event_id__exact=query_kwargs['query'])
  +
  +                events = events.filter(q)
   
               if query_kwargs['tags']:
                   try:
  
verification_info: {"golden_diff": "diff --git a/src/sentry/api/endpoints/group_events.py b/src/sentry/api/endpoints/group_events.py\n--- a/src/sentry/api/endpoints/group_events.py\n+++ b/src/sentry/api/endpoints/group_events.py\n@@ -12,6 +12,7 @@\n from sentry.utils.apidocs import scenario, attach_scenarios\n from rest_framework.response import Response\n from sentry.search.utils import InvalidQuery\n+from django.db.models import Q\n \n \n @scenario('ListAvailableSamples')\n@@ -40,6 +41,7 @@\n         )\n \n         query = request.GET.get('query')\n+\n         if query:\n             try:\n                 query_kwargs = parse_query(group.project, query, request.user)\n@@ -47,9 +49,12 @@\n                 return Response({'detail': six.text_type(exc)}, status=400)\n \n             if query_kwargs['query']:\n-                events = events.filter(\n-                    message__icontains=query_kwargs['query'],\n-                )\n+                q = Q(message__icontains=query_kwargs['query'])\n+\n+                if len(query) == 32:\n+                    q |= Q(event_id__exact=query_kwargs['query'])\n+\n+                events = events.filter(q)\n \n             if query_kwargs['tags']:\n                 try:\n", "issue": "Search related events by event ID\n\r\n![image](https://user-images.githubusercontent.com/2153/29005586-1dfdfbf6-7a93-11e7-9127-c82c0356b4c6.png)\r\n\r\nRight now you can search [by message or tags](https://github.com/getsentry/sentry/blob/master/src/sentry/api/endpoints/group_events.py#L104), but not individual event ID. This is useful when trying to locate a specific event. More useful now that sampling has been disabled by default.\r\n\r\nWe should also add a column for event ID here.\r\n\r\nRefs #3147\n", "before_files": [{"content": "from __future__ import absolute_import\n\nimport six\n\nfrom sentry import tagstore\nfrom sentry.api.base import DocSection, EnvironmentMixin\nfrom sentry.api.bases import GroupEndpoint\nfrom sentry.api.serializers import serialize\nfrom sentry.api.paginator import DateTimePaginator\nfrom sentry.models import Environment, Event, Group\nfrom sentry.search.utils import parse_query\nfrom sentry.utils.apidocs import scenario, attach_scenarios\nfrom rest_framework.response import Response\nfrom sentry.search.utils import InvalidQuery\n\n\n@scenario('ListAvailableSamples')\ndef list_available_samples_scenario(runner):\n    group = Group.objects.filter(project=runner.default_project).first()\n    runner.request(method='GET', path='/issues/%s/events/' % group.id)\n\n\nclass GroupEventsEndpoint(GroupEndpoint, EnvironmentMixin):\n    doc_section = DocSection.EVENTS\n\n    @attach_scenarios([list_available_samples_scenario])\n    def get(self, request, group):\n        \"\"\"\n        List an Issue's Events\n        ``````````````````````\n\n        This endpoint lists an issue's events.\n\n        :pparam string issue_id: the ID of the issue to retrieve.\n        :auth: required\n        \"\"\"\n\n        events = Event.objects.filter(\n            group_id=group.id,\n        )\n\n        query = request.GET.get('query')\n        if query:\n            try:\n                query_kwargs = parse_query(group.project, query, request.user)\n            except InvalidQuery as exc:\n                return Response({'detail': six.text_type(exc)}, status=400)\n\n            if query_kwargs['query']:\n                events = events.filter(\n                    message__icontains=query_kwargs['query'],\n                )\n\n            if query_kwargs['tags']:\n                try:\n                    environment_id = self._get_environment_id_from_request(\n                        request, group.project.organization_id)\n                except Environment.DoesNotExist:\n                    event_ids = []\n                else:\n                    event_ids = tagstore.get_group_event_ids(\n                        group.project_id, group.id, environment_id, query_kwargs['tags'])\n\n                if event_ids:\n                    events = events.filter(\n                        id__in=event_ids,\n                    )\n                else:\n                    events = events.none()\n\n        return self.paginate(\n            request=request,\n            queryset=events,\n            order_by='-datetime',\n            on_results=lambda x: serialize(x, request.user),\n            paginator_cls=DateTimePaginator,\n        )\n", "path": "src/sentry/api/endpoints/group_events.py"}], "after_files": [{"content": "from __future__ import absolute_import\n\nimport six\n\nfrom sentry import tagstore\nfrom sentry.api.base import DocSection, EnvironmentMixin\nfrom sentry.api.bases import GroupEndpoint\nfrom sentry.api.serializers import serialize\nfrom sentry.api.paginator import DateTimePaginator\nfrom sentry.models import Environment, Event, Group\nfrom sentry.search.utils import parse_query\nfrom sentry.utils.apidocs import scenario, attach_scenarios\nfrom rest_framework.response import Response\nfrom sentry.search.utils import InvalidQuery\nfrom django.db.models import Q\n\n\n@scenario('ListAvailableSamples')\ndef list_available_samples_scenario(runner):\n    group = Group.objects.filter(project=runner.default_project).first()\n    runner.request(method='GET', path='/issues/%s/events/' % group.id)\n\n\nclass GroupEventsEndpoint(GroupEndpoint, EnvironmentMixin):\n    doc_section = DocSection.EVENTS\n\n    @attach_scenarios([list_available_samples_scenario])\n    def get(self, request, group):\n        \"\"\"\n        List an Issue's Events\n        ``````````````````````\n\n        This endpoint lists an issue's events.\n\n        :pparam string issue_id: the ID of the issue to retrieve.\n        :auth: required\n        \"\"\"\n\n        events = Event.objects.filter(\n            group_id=group.id,\n        )\n\n        query = request.GET.get('query')\n\n        if query:\n            try:\n                query_kwargs = parse_query(group.project, query, request.user)\n            except InvalidQuery as exc:\n                return Response({'detail': six.text_type(exc)}, status=400)\n\n            if query_kwargs['query']:\n                q = Q(message__icontains=query_kwargs['query'])\n\n                if len(query) == 32:\n                    q |= Q(event_id__exact=query_kwargs['query'])\n\n                events = events.filter(q)\n\n            if query_kwargs['tags']:\n                try:\n                    environment_id = self._get_environment_id_from_request(\n                        request, group.project.organization_id)\n                except Environment.DoesNotExist:\n                    event_ids = []\n                else:\n                    event_ids = tagstore.get_group_event_ids(\n                        group.project_id, group.id, environment_id, query_kwargs['tags'])\n\n                if event_ids:\n                    events = events.filter(\n                        id__in=event_ids,\n                    )\n                else:\n                    events = events.none()\n\n        return self.paginate(\n            request=request,\n            queryset=events,\n            order_by='-datetime',\n            on_results=lambda x: serialize(x, request.user),\n            paginator_cls=DateTimePaginator,\n        )\n", "path": "src/sentry/api/endpoints/group_events.py"}]}