prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Add the practice session experience to the topic viewer
  Add an option in the topic viewer page that can start the practice session, based on the skills that are part of the topic.
  Add the practice session experience to the topic viewer
  Add an option in the topic viewer page that can start the practice session, based on the skills that are part of the topic.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `core/controllers/topic_viewer.py`
  Content:
  ```
  1 # Copyright 2018 The Oppia Authors. All Rights Reserved.
  2 #
  3 # Licensed under the Apache License, Version 2.0 (the "License");
  4 # you may not use this file except in compliance with the License.
  5 # You may obtain a copy of the License at
  6 #
  7 #      http://www.apache.org/licenses/LICENSE-2.0
  8 #
  9 # Unless required by applicable law or agreed to in writing, software
  10 # distributed under the License is distributed on an "AS-IS" BASIS,
  11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12 # See the License for the specific language governing permissions and
  13 # limitations under the License.
  14 
  15 """Controllers for the topic viewer page."""
  16 
  17 from constants import constants
  18 from core.controllers import acl_decorators
  19 from core.controllers import base
  20 from core.domain import story_services
  21 from core.domain import topic_services
  22 import feconf
  23 
  24 
  25 class TopicViewerPage(base.BaseHandler):
  26     """Renders the topic viewer page."""
  27 
  28     @acl_decorators.can_access_topic_viewer_page
  29     def get(self, _):
  30         """Handles GET requests."""
  31 
  32         if not constants.ENABLE_NEW_STRUCTURE_PLAYERS:
  33             raise self.PageNotFoundException
  34 
  35         self.render_template('dist/topic-viewer-page.mainpage.html')
  36 
  37 
  38 class TopicPageDataHandler(base.BaseHandler):
  39     """Manages the data that needs to be displayed to a learner on the topic
  40     viewer page.
  41     """
  42     GET_HANDLER_ERROR_RETURN_TYPE = feconf.HANDLER_TYPE_JSON
  43 
  44     @acl_decorators.can_access_topic_viewer_page
  45     def get(self, topic_name):
  46         """Handles GET requests."""
  47 
  48         if not constants.ENABLE_NEW_STRUCTURE_PLAYERS:
  49             raise self.PageNotFoundException
  50 
  51         topic = topic_services.get_topic_by_name(topic_name)
  52 
  53         canonical_story_summaries = [
  54             story_services.get_story_summary_by_id(
  55                 canonical_story_id) for canonical_story_id
  56             in topic.canonical_story_ids]
  57 
  58         additional_story_summaries = [
  59             story_services.get_story_summary_by_id(
  60                 additional_story_id) for additional_story_id
  61             in topic.additional_story_ids]
  62 
  63         canonical_story_dicts = [
  64             summary.to_human_readable_dict() for summary
  65             in canonical_story_summaries]
  66 
  67         additional_story_dicts = [
  68             summary.to_human_readable_dict() for summary
  69             in additional_story_summaries]
  70 
  71         uncategorized_skill_ids = topic.get_all_uncategorized_skill_ids()
  72         subtopics = topic.get_all_subtopics()
  73 
  74         self.values.update({
  75             'topic_name': topic.name,
  76             'canonical_story_dicts': canonical_story_dicts,
  77             'additional_story_dicts': additional_story_dicts,
  78             'uncategorized_skill_ids': uncategorized_skill_ids,
  79             'subtopics': subtopics
  80         })
  81         self.render_json(self.values)
  82
  ```
  --- 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/core/controllers/topic_viewer.py b/core/controllers/topic_viewer.py
  --- a/core/controllers/topic_viewer.py
  +++ b/core/controllers/topic_viewer.py
  @@ -73,6 +73,7 @@
   
           self.values.update({
               'topic_name': topic.name,
  +            'topic_id': topic.id,
               'canonical_story_dicts': canonical_story_dicts,
               'additional_story_dicts': additional_story_dicts,
               'uncategorized_skill_ids': uncategorized_skill_ids,
  
verification_info: {"golden_diff": "diff --git a/core/controllers/topic_viewer.py b/core/controllers/topic_viewer.py\n--- a/core/controllers/topic_viewer.py\n+++ b/core/controllers/topic_viewer.py\n@@ -73,6 +73,7 @@\n \n         self.values.update({\n             'topic_name': topic.name,\n+            'topic_id': topic.id,\n             'canonical_story_dicts': canonical_story_dicts,\n             'additional_story_dicts': additional_story_dicts,\n             'uncategorized_skill_ids': uncategorized_skill_ids,\n", "issue": "Add the practice session experience to the topic viewer\nAdd an option in the topic viewer page that can start the practice session, based on the skills that are part of the topic.\nAdd the practice session experience to the topic viewer\nAdd an option in the topic viewer page that can start the practice session, based on the skills that are part of the topic.\n", "before_files": [{"content": "# Copyright 2018 The Oppia Authors. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS-IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Controllers for the topic viewer page.\"\"\"\n\nfrom constants import constants\nfrom core.controllers import acl_decorators\nfrom core.controllers import base\nfrom core.domain import story_services\nfrom core.domain import topic_services\nimport feconf\n\n\nclass TopicViewerPage(base.BaseHandler):\n    \"\"\"Renders the topic viewer page.\"\"\"\n\n    @acl_decorators.can_access_topic_viewer_page\n    def get(self, _):\n        \"\"\"Handles GET requests.\"\"\"\n\n        if not constants.ENABLE_NEW_STRUCTURE_PLAYERS:\n            raise self.PageNotFoundException\n\n        self.render_template('dist/topic-viewer-page.mainpage.html')\n\n\nclass TopicPageDataHandler(base.BaseHandler):\n    \"\"\"Manages the data that needs to be displayed to a learner on the topic\n    viewer page.\n    \"\"\"\n    GET_HANDLER_ERROR_RETURN_TYPE = feconf.HANDLER_TYPE_JSON\n\n    @acl_decorators.can_access_topic_viewer_page\n    def get(self, topic_name):\n        \"\"\"Handles GET requests.\"\"\"\n\n        if not constants.ENABLE_NEW_STRUCTURE_PLAYERS:\n            raise self.PageNotFoundException\n\n        topic = topic_services.get_topic_by_name(topic_name)\n\n        canonical_story_summaries = [\n            story_services.get_story_summary_by_id(\n                canonical_story_id) for canonical_story_id\n            in topic.canonical_story_ids]\n\n        additional_story_summaries = [\n            story_services.get_story_summary_by_id(\n                additional_story_id) for additional_story_id\n            in topic.additional_story_ids]\n\n        canonical_story_dicts = [\n            summary.to_human_readable_dict() for summary\n            in canonical_story_summaries]\n\n        additional_story_dicts = [\n            summary.to_human_readable_dict() for summary\n            in additional_story_summaries]\n\n        uncategorized_skill_ids = topic.get_all_uncategorized_skill_ids()\n        subtopics = topic.get_all_subtopics()\n\n        self.values.update({\n            'topic_name': topic.name,\n            'canonical_story_dicts': canonical_story_dicts,\n            'additional_story_dicts': additional_story_dicts,\n            'uncategorized_skill_ids': uncategorized_skill_ids,\n            'subtopics': subtopics\n        })\n        self.render_json(self.values)\n", "path": "core/controllers/topic_viewer.py"}], "after_files": [{"content": "# Copyright 2018 The Oppia Authors. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS-IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Controllers for the topic viewer page.\"\"\"\n\nfrom constants import constants\nfrom core.controllers import acl_decorators\nfrom core.controllers import base\nfrom core.domain import story_services\nfrom core.domain import topic_services\nimport feconf\n\n\nclass TopicViewerPage(base.BaseHandler):\n    \"\"\"Renders the topic viewer page.\"\"\"\n\n    @acl_decorators.can_access_topic_viewer_page\n    def get(self, _):\n        \"\"\"Handles GET requests.\"\"\"\n\n        if not constants.ENABLE_NEW_STRUCTURE_PLAYERS:\n            raise self.PageNotFoundException\n\n        self.render_template('dist/topic-viewer-page.mainpage.html')\n\n\nclass TopicPageDataHandler(base.BaseHandler):\n    \"\"\"Manages the data that needs to be displayed to a learner on the topic\n    viewer page.\n    \"\"\"\n    GET_HANDLER_ERROR_RETURN_TYPE = feconf.HANDLER_TYPE_JSON\n\n    @acl_decorators.can_access_topic_viewer_page\n    def get(self, topic_name):\n        \"\"\"Handles GET requests.\"\"\"\n\n        if not constants.ENABLE_NEW_STRUCTURE_PLAYERS:\n            raise self.PageNotFoundException\n\n        topic = topic_services.get_topic_by_name(topic_name)\n\n        canonical_story_summaries = [\n            story_services.get_story_summary_by_id(\n                canonical_story_id) for canonical_story_id\n            in topic.canonical_story_ids]\n\n        additional_story_summaries = [\n            story_services.get_story_summary_by_id(\n                additional_story_id) for additional_story_id\n            in topic.additional_story_ids]\n\n        canonical_story_dicts = [\n            summary.to_human_readable_dict() for summary\n            in canonical_story_summaries]\n\n        additional_story_dicts = [\n            summary.to_human_readable_dict() for summary\n            in additional_story_summaries]\n\n        uncategorized_skill_ids = topic.get_all_uncategorized_skill_ids()\n        subtopics = topic.get_all_subtopics()\n\n        self.values.update({\n            'topic_name': topic.name,\n            'topic_id': topic.id,\n            'canonical_story_dicts': canonical_story_dicts,\n            'additional_story_dicts': additional_story_dicts,\n            'uncategorized_skill_ids': uncategorized_skill_ids,\n            'subtopics': subtopics\n        })\n        self.render_json(self.values)\n", "path": "core/controllers/topic_viewer.py"}]}