From 6a42f1ad0c70ff563acb8a2d655ffc8c84013919 Mon Sep 17 00:00:00 2001
From: XnpioChV <xnpiochv@gmail.com>
Date: Wed, 27 Nov 2024 12:38:05 -0500
Subject: [PATCH 1/8] refactor: Update Get block OLX to support versions

---
 .../content_libraries/tests/base.py           |  4 ++--
 .../tests/test_content_libraries.py           |  8 +++++++
 .../djangoapps/content_libraries/views.py     |  8 ++++++-
 openedx/core/djangoapps/xblock/api.py         | 24 ++++++++++++++-----
 .../xblock/runtime/learning_core_runtime.py   | 18 ++++++++++----
 5 files changed, 48 insertions(+), 14 deletions(-)

diff --git a/openedx/core/djangoapps/content_libraries/tests/base.py b/openedx/core/djangoapps/content_libraries/tests/base.py
index 638c053f62c3..f76d4a80dd3f 100644
--- a/openedx/core/djangoapps/content_libraries/tests/base.py
+++ b/openedx/core/djangoapps/content_libraries/tests/base.py
@@ -242,9 +242,9 @@ def _delete_library_block(self, block_key, expect_response=200):
         """ Delete a specific block from the library """
         self._api('delete', URL_LIB_BLOCK.format(block_key=block_key), None, expect_response)
 
-    def _get_library_block_olx(self, block_key, expect_response=200):
+    def _get_library_block_olx(self, block_key, version="draft", expect_response=200):
         """ Get the OLX of a specific block in the library """
-        result = self._api('get', URL_LIB_BLOCK_OLX.format(block_key=block_key), None, expect_response)
+        result = self._api('get', URL_LIB_BLOCK_OLX.format(block_key=block_key), {"version": version}, expect_response)
         if expect_response == 200:
             return result["olx"]
         return result
diff --git a/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py b/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py
index 18d4ec591604..b6aac74cbea0 100644
--- a/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py
+++ b/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py
@@ -369,6 +369,14 @@ def test_library_blocks(self):  # pylint: disable=too-many-statements
         assert published_block_data['published_by'] == "Bob"
         assert published_block_data['has_unpublished_changes'] is False
 
+        # Updated OLX and verify draft and published version
+        published_olx = new_olx
+        draft_olx = "<problem><p>Not Published OLX</p></problem>"
+
+        self._set_library_block_olx(block_id, draft_olx)
+        assert self._get_library_block_olx(block_id, version='published') == published_olx
+        assert self._get_library_block_olx(block_id, version='draft') == draft_olx
+
         # fin
 
     def test_library_blocks_studio_view(self):
diff --git a/openedx/core/djangoapps/content_libraries/views.py b/openedx/core/djangoapps/content_libraries/views.py
index e30e58e75a26..4d23315948da 100644
--- a/openedx/core/djangoapps/content_libraries/views.py
+++ b/openedx/core/djangoapps/content_libraries/views.py
@@ -122,6 +122,7 @@
 from openedx.core.lib.api.view_utils import view_auth_classes
 from openedx.core.djangoapps.safe_sessions.middleware import mark_user_change_as_expected
 from openedx.core.djangoapps.xblock import api as xblock_api
+from openedx.core.djangoapps.xblock.rest_api.url_converters import VersionConverter
 
 from .models import ContentLibrary, LtiGradedResource, LtiProfile
 
@@ -713,8 +714,13 @@ def get(self, request, usage_key_str):
         Get the block's OLX
         """
         key = LibraryUsageLocatorV2.from_string(usage_key_str)
+        version = request.query_params.get('version', None)
+
+        # Use the default `LatestVersion.AUTO` if `version` is None
+        version = VersionConverter().to_python(version)
+
         api.require_permission_for_library_key(key.lib_key, request.user, permissions.CAN_VIEW_THIS_CONTENT_LIBRARY)
-        xml_str = xblock_api.get_block_draft_olx(key)
+        xml_str = xblock_api.get_block_olx(key, request.user, version=version)
         return Response(LibraryXBlockOlxSerializer({"olx": xml_str}).data)
 
     @convert_exceptions
diff --git a/openedx/core/djangoapps/xblock/api.py b/openedx/core/djangoapps/xblock/api.py
index 00bb8bc356a6..23760baf7cb4 100644
--- a/openedx/core/djangoapps/xblock/api.py
+++ b/openedx/core/djangoapps/xblock/api.py
@@ -208,13 +208,25 @@ def get_component_from_usage_key(usage_key: UsageKeyV2) -> Component:
     )
 
 
-def get_block_draft_olx(usage_key: UsageKeyV2) -> str:
-    """
-    Get the OLX source of the draft version of the given Learning-Core-backed XBlock.
-    """
-    # Inefficient but simple approach. Optimize later if needed.
+def get_block_olx(
+    usage_key: UsageKeyV2,
+    user: UserType,
+    *,
+    version: int | LatestVersion = LatestVersion.AUTO
+) -> str:
     component = get_component_from_usage_key(usage_key)
-    component_version = component.versioning.draft
+    runtime = get_runtime(user=user)
+    version = runtime.get_auto_latest_version(version)
+
+    if version == LatestVersion.DRAFT:
+        component_version = component.versioning.draft
+    elif version == LatestVersion.PUBLISHED:
+        component_version = component.versioning.published
+    else:
+        assert isinstance(version, int)
+        component_version = component.versioning.version_num(version)
+    if component_version is None:
+        raise NoSuchUsage(usage_key)
 
     # TODO: we should probably make a method on ComponentVersion that returns
     # a content based on the name. Accessing by componentversioncontent__key is
diff --git a/openedx/core/djangoapps/xblock/runtime/learning_core_runtime.py b/openedx/core/djangoapps/xblock/runtime/learning_core_runtime.py
index fd2e867a3a8f..79dcc7a2f693 100644
--- a/openedx/core/djangoapps/xblock/runtime/learning_core_runtime.py
+++ b/openedx/core/djangoapps/xblock/runtime/learning_core_runtime.py
@@ -178,11 +178,7 @@ def get_block(self, usage_key, for_parent=None, *, version: int | LatestVersion
         # just get it the easy way.
         component = self._get_component_from_usage_key(usage_key)
 
-        if version == LatestVersion.AUTO:
-            if self.authored_data_mode == AuthoredDataMode.DEFAULT_DRAFT:
-                version = LatestVersion.DRAFT
-            else:
-                version = LatestVersion.PUBLISHED
+        version = self.get_auto_latest_version(version)
         if self.authored_data_mode == AuthoredDataMode.STRICTLY_PUBLISHED and version != LatestVersion.PUBLISHED:
             raise ValidationError("This runtime only allows accessing the published version of components")
         if version == LatestVersion.DRAFT:
@@ -316,6 +312,18 @@ def save_block(self, block):
             )
         self.authored_data_store.mark_unchanged(block)
 
+    def get_auto_latest_version(self, version: int | LatestVersion) -> int | LatestVersion:
+        """
+        Gets the actual LatesVersion if is `LatestVersion.AUTO`;
+        otherwise, returns the same value.
+        """
+        if version == LatestVersion.AUTO:
+            if self.authored_data_mode == AuthoredDataMode.DEFAULT_DRAFT:
+                return LatestVersion.DRAFT
+            else:
+                return LatestVersion.PUBLISHED
+        return version
+
     def _get_component_from_usage_key(self, usage_key):
         """
         Note that Components aren't ever really truly deleted, so this will

From 7a287b52fcdb80e69fe5f4e7f35707d75a9e4c4d Mon Sep 17 00:00:00 2001
From: XnpioChV <xnpiochv@gmail.com>
Date: Wed, 27 Nov 2024 13:13:10 -0500
Subject: [PATCH 2/8] refactor: Adds string_to_version func in xblock_api

---
 openedx/core/djangoapps/content_libraries/views.py | 3 +--
 openedx/core/djangoapps/xblock/api.py              | 8 ++++++++
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/openedx/core/djangoapps/content_libraries/views.py b/openedx/core/djangoapps/content_libraries/views.py
index 4d23315948da..12a262a934b8 100644
--- a/openedx/core/djangoapps/content_libraries/views.py
+++ b/openedx/core/djangoapps/content_libraries/views.py
@@ -122,7 +122,6 @@
 from openedx.core.lib.api.view_utils import view_auth_classes
 from openedx.core.djangoapps.safe_sessions.middleware import mark_user_change_as_expected
 from openedx.core.djangoapps.xblock import api as xblock_api
-from openedx.core.djangoapps.xblock.rest_api.url_converters import VersionConverter
 
 from .models import ContentLibrary, LtiGradedResource, LtiProfile
 
@@ -717,7 +716,7 @@ def get(self, request, usage_key_str):
         version = request.query_params.get('version', None)
 
         # Use the default `LatestVersion.AUTO` if `version` is None
-        version = VersionConverter().to_python(version)
+        version = xblock_api.string_to_version(version)
 
         api.require_permission_for_library_key(key.lib_key, request.user, permissions.CAN_VIEW_THIS_CONTENT_LIBRARY)
         xml_str = xblock_api.get_block_olx(key, request.user, version=version)
diff --git a/openedx/core/djangoapps/xblock/api.py b/openedx/core/djangoapps/xblock/api.py
index 23760baf7cb4..74441799be27 100644
--- a/openedx/core/djangoapps/xblock/api.py
+++ b/openedx/core/djangoapps/xblock/api.py
@@ -33,6 +33,7 @@
     LearningCoreXBlockRuntime,
 )
 from .data import CheckPerm, LatestVersion
+from .rest_api.url_converters import VersionConverter
 from .utils import get_secure_token_for_xblock_handler, get_xblock_id_for_anonymous_user
 
 from .runtime.learning_core_runtime import LearningCoreXBlockRuntime
@@ -214,6 +215,9 @@ def get_block_olx(
     *,
     version: int | LatestVersion = LatestVersion.AUTO
 ) -> str:
+    """
+    Get the OLX source of the of the given Learning-Core-backed XBlock and a version.
+    """
     component = get_component_from_usage_key(usage_key)
     runtime = get_runtime(user=user)
     version = runtime.get_auto_latest_version(version)
@@ -319,3 +323,7 @@ def get_handler_url(
     # can be called by the XBlock from python as well and in that case we don't
     # have access to the request.
     return site_root_url + path
+
+def string_to_version(version: str | None) -> LatestVersion | int:
+    """ Convert from string to LatestVersion or integer version spec """
+    return VersionConverter().to_python(version)

From ba91357461166501fe219a6df97cf466d291b69b Mon Sep 17 00:00:00 2001
From: XnpioChV <xnpiochv@gmail.com>
Date: Wed, 27 Nov 2024 13:31:39 -0500
Subject: [PATCH 3/8] fix: Lint issues

---
 openedx/core/djangoapps/xblock/api.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/openedx/core/djangoapps/xblock/api.py b/openedx/core/djangoapps/xblock/api.py
index 74441799be27..c0bda6ca5c63 100644
--- a/openedx/core/djangoapps/xblock/api.py
+++ b/openedx/core/djangoapps/xblock/api.py
@@ -324,6 +324,7 @@ def get_handler_url(
     # have access to the request.
     return site_root_url + path
 
+
 def string_to_version(version: str | None) -> LatestVersion | int:
     """ Convert from string to LatestVersion or integer version spec """
     return VersionConverter().to_python(version)

From a66890d1cdc0c87464fbc15d5dbf8ebbd0ea38b2 Mon Sep 17 00:00:00 2001
From: XnpioChV <xnpiochv@gmail.com>
Date: Fri, 29 Nov 2024 06:34:32 -0500
Subject: [PATCH 4/8] refactor: New view created and deprecate the old view

---
 .../core/djangoapps/content_libraries/views.py   |  3 +++
 openedx/core/djangoapps/xblock/api.py            | 15 +++++++++++----
 .../djangoapps/xblock/rest_api/serializers.py    | 10 ++++++++++
 openedx/core/djangoapps/xblock/rest_api/urls.py  |  2 ++
 openedx/core/djangoapps/xblock/rest_api/views.py | 16 ++++++++++++++++
 .../xblock/runtime/learning_core_runtime.py      | 15 ++-------------
 openedx/core/djangoapps/xblock/utils.py          | 14 ++++++++++++++
 7 files changed, 58 insertions(+), 17 deletions(-)
 create mode 100644 openedx/core/djangoapps/xblock/rest_api/serializers.py

diff --git a/openedx/core/djangoapps/content_libraries/views.py b/openedx/core/djangoapps/content_libraries/views.py
index 12a262a934b8..df8d10190c64 100644
--- a/openedx/core/djangoapps/content_libraries/views.py
+++ b/openedx/core/djangoapps/content_libraries/views.py
@@ -710,6 +710,9 @@ class LibraryBlockOlxView(APIView):
     @convert_exceptions
     def get(self, request, usage_key_str):
         """
+        DEPRECATED. Use get_block_olx_view() in xblock REST-API.
+        Can be removed post-Teak.
+        
         Get the block's OLX
         """
         key = LibraryUsageLocatorV2.from_string(usage_key_str)
diff --git a/openedx/core/djangoapps/xblock/api.py b/openedx/core/djangoapps/xblock/api.py
index c0bda6ca5c63..a6f37dbd432e 100644
--- a/openedx/core/djangoapps/xblock/api.py
+++ b/openedx/core/djangoapps/xblock/api.py
@@ -34,7 +34,11 @@
 )
 from .data import CheckPerm, LatestVersion
 from .rest_api.url_converters import VersionConverter
-from .utils import get_secure_token_for_xblock_handler, get_xblock_id_for_anonymous_user
+from .utils import (
+    get_secure_token_for_xblock_handler,
+    get_xblock_id_for_anonymous_user,
+    get_auto_latest_version,
+)
 
 from .runtime.learning_core_runtime import LearningCoreXBlockRuntime
 
@@ -211,7 +215,6 @@ def get_component_from_usage_key(usage_key: UsageKeyV2) -> Component:
 
 def get_block_olx(
     usage_key: UsageKeyV2,
-    user: UserType,
     *,
     version: int | LatestVersion = LatestVersion.AUTO
 ) -> str:
@@ -219,8 +222,7 @@ def get_block_olx(
     Get the OLX source of the of the given Learning-Core-backed XBlock and a version.
     """
     component = get_component_from_usage_key(usage_key)
-    runtime = get_runtime(user=user)
-    version = runtime.get_auto_latest_version(version)
+    version = get_auto_latest_version(version)
 
     if version == LatestVersion.DRAFT:
         component_version = component.versioning.draft
@@ -240,6 +242,11 @@ def get_block_olx(
     return content.text
 
 
+def get_block_draft_olx(usage_key: UsageKeyV2) -> str:
+    """ DEPRECATED. Use get_block_olx(). Can be removed post-Teak. """
+    return get_block_olx(usage_key, version=LatestVersion.DRAFT)
+
+
 def render_block_view(block, view_name, user):  # pylint: disable=unused-argument
     """
     Get the HTML, JS, and CSS needed to render the given XBlock view.
diff --git a/openedx/core/djangoapps/xblock/rest_api/serializers.py b/openedx/core/djangoapps/xblock/rest_api/serializers.py
new file mode 100644
index 000000000000..c5971f0895d7
--- /dev/null
+++ b/openedx/core/djangoapps/xblock/rest_api/serializers.py
@@ -0,0 +1,10 @@
+"""
+Serializers for the xblock REST API
+"""
+from rest_framework import serializers
+
+class XBlockOlxSerializer(serializers.Serializer):
+    """
+    Serializer for representing an XBlock's OLX
+    """
+    olx = serializers.CharField()
diff --git a/openedx/core/djangoapps/xblock/rest_api/urls.py b/openedx/core/djangoapps/xblock/rest_api/urls.py
index ee41b43f5b39..1ed169b4a525 100644
--- a/openedx/core/djangoapps/xblock/rest_api/urls.py
+++ b/openedx/core/djangoapps/xblock/rest_api/urls.py
@@ -19,6 +19,8 @@
     path('', views.block_metadata),
     # get/post full json fields of an XBlock:
     path('fields/', views.BlockFieldsView.as_view()),
+    # Get the OLX source code of the specified block
+    path('fields/olx/', views.get_block_olx_view),
     # render one of this XBlock's views (e.g. student_view)
     path('view/<str:view_name>/', views.render_block_view),
     # get the URL needed to call this XBlock's handlers
diff --git a/openedx/core/djangoapps/xblock/rest_api/views.py b/openedx/core/djangoapps/xblock/rest_api/views.py
index d69edcbfd51c..6e709b9cef19 100644
--- a/openedx/core/djangoapps/xblock/rest_api/views.py
+++ b/openedx/core/djangoapps/xblock/rest_api/views.py
@@ -33,9 +33,11 @@
     get_handler_url as _get_handler_url,
     load_block,
     render_block_view as _render_block_view,
+    get_block_olx,
 )
 from ..utils import validate_secure_token_for_xblock_handler
 from .url_converters import VersionConverter
+from .serializers import XBlockOlxSerializer
 
 User = get_user_model()
 
@@ -213,6 +215,20 @@ def xblock_handler(
     return response
 
 
+@api_view(['GET'])
+@view_auth_classes(is_authenticated=False)
+def get_block_olx_view(
+    request,
+    usage_key: UsageKeyV2,
+    version: LatestVersion | int = LatestVersion.AUTO,
+):
+    context_impl = get_learning_context_impl(usage_key)
+    if not context_impl.can_view_block_for_editing(request.user, usage_key):
+        raise PermissionDenied(f"You don't have permission to access the OLX of component '{usage_key}'.")
+    olx = get_block_olx(usage_key, version=version)
+    return Response(XBlockOlxSerializer({"olx": olx}).data)
+
+
 def cors_allow_xblock_handler(sender, request, **kwargs):  # lint-amnesty, pylint: disable=unused-argument
     """
     Sandboxed XBlocks need to be able to call XBlock handlers via POST,
diff --git a/openedx/core/djangoapps/xblock/runtime/learning_core_runtime.py b/openedx/core/djangoapps/xblock/runtime/learning_core_runtime.py
index 79dcc7a2f693..dde2084e54cd 100644
--- a/openedx/core/djangoapps/xblock/runtime/learning_core_runtime.py
+++ b/openedx/core/djangoapps/xblock/runtime/learning_core_runtime.py
@@ -24,6 +24,7 @@
 from openedx.core.lib.xblock_serializer.api import serialize_modulestore_block_for_learning_core
 from openedx.core.lib.xblock_serializer.data import StaticFile
 from ..data import AuthoredDataMode, LatestVersion
+from ..utils import get_auto_latest_version
 from ..learning_context.manager import get_learning_context_impl
 from .runtime import XBlockRuntime
 
@@ -178,7 +179,7 @@ def get_block(self, usage_key, for_parent=None, *, version: int | LatestVersion
         # just get it the easy way.
         component = self._get_component_from_usage_key(usage_key)
 
-        version = self.get_auto_latest_version(version)
+        version = get_auto_latest_version(version)
         if self.authored_data_mode == AuthoredDataMode.STRICTLY_PUBLISHED and version != LatestVersion.PUBLISHED:
             raise ValidationError("This runtime only allows accessing the published version of components")
         if version == LatestVersion.DRAFT:
@@ -312,18 +313,6 @@ def save_block(self, block):
             )
         self.authored_data_store.mark_unchanged(block)
 
-    def get_auto_latest_version(self, version: int | LatestVersion) -> int | LatestVersion:
-        """
-        Gets the actual LatesVersion if is `LatestVersion.AUTO`;
-        otherwise, returns the same value.
-        """
-        if version == LatestVersion.AUTO:
-            if self.authored_data_mode == AuthoredDataMode.DEFAULT_DRAFT:
-                return LatestVersion.DRAFT
-            else:
-                return LatestVersion.PUBLISHED
-        return version
-
     def _get_component_from_usage_key(self, usage_key):
         """
         Note that Components aren't ever really truly deleted, so this will
diff --git a/openedx/core/djangoapps/xblock/utils.py b/openedx/core/djangoapps/xblock/utils.py
index 375bb9d21450..882037c6b3b1 100644
--- a/openedx/core/djangoapps/xblock/utils.py
+++ b/openedx/core/djangoapps/xblock/utils.py
@@ -11,6 +11,9 @@
 import crum
 from django.conf import settings
 
+from openedx.core.djangoapps.xblock.apps import get_xblock_app_config
+
+from .data import AuthoredDataMode, LatestVersion
 
 def get_secure_token_for_xblock_handler(user_id, block_key_str, time_idx=0):
     """
@@ -167,3 +170,14 @@ def get_xblock_id_for_anonymous_user(user):
         return current_request.session["xblock_id_for_anonymous_user"]
     else:
         raise RuntimeError("Cannot get a user ID for an anonymous user outside of an HTTP request context.")
+
+
+def get_auto_latest_version(version: int | LatestVersion) -> int | LatestVersion:
+    """
+    Gets the actual LatestVersion if is `LatestVersion.AUTO`;
+    otherwise, returns the same value.
+    """
+    authored_data_mode = get_xblock_app_config().get_runtime_params()["authored_data_mode"]
+    if version == LatestVersion.AUTO:
+        version = LatestVersion.DRAFT if authored_data_mode == AuthoredDataMode.DEFAULT_DRAFT else LatestVersion.PUBLISHED
+    return version
\ No newline at end of file

From 46ac9e2da497011bba8558679d890164c8948fb7 Mon Sep 17 00:00:00 2001
From: XnpioChV <xnpiochv@gmail.com>
Date: Fri, 29 Nov 2024 22:15:09 -0500
Subject: [PATCH 5/8] refactor: Add suggestions from review feedback

---
 .../content_libraries/tests/test_content_libraries.py    | 8 --------
 openedx/core/djangoapps/content_libraries/views.py       | 9 ++-------
 openedx/core/djangoapps/xblock/rest_api/serializers.py   | 1 +
 openedx/core/djangoapps/xblock/rest_api/urls.py          | 2 +-
 openedx/core/djangoapps/xblock/rest_api/views.py         | 3 +++
 openedx/core/djangoapps/xblock/utils.py                  | 7 ++++---
 6 files changed, 11 insertions(+), 19 deletions(-)

diff --git a/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py b/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py
index b6aac74cbea0..18d4ec591604 100644
--- a/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py
+++ b/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py
@@ -369,14 +369,6 @@ def test_library_blocks(self):  # pylint: disable=too-many-statements
         assert published_block_data['published_by'] == "Bob"
         assert published_block_data['has_unpublished_changes'] is False
 
-        # Updated OLX and verify draft and published version
-        published_olx = new_olx
-        draft_olx = "<problem><p>Not Published OLX</p></problem>"
-
-        self._set_library_block_olx(block_id, draft_olx)
-        assert self._get_library_block_olx(block_id, version='published') == published_olx
-        assert self._get_library_block_olx(block_id, version='draft') == draft_olx
-
         # fin
 
     def test_library_blocks_studio_view(self):
diff --git a/openedx/core/djangoapps/content_libraries/views.py b/openedx/core/djangoapps/content_libraries/views.py
index df8d10190c64..3dc7f538df86 100644
--- a/openedx/core/djangoapps/content_libraries/views.py
+++ b/openedx/core/djangoapps/content_libraries/views.py
@@ -712,17 +712,12 @@ def get(self, request, usage_key_str):
         """
         DEPRECATED. Use get_block_olx_view() in xblock REST-API.
         Can be removed post-Teak.
-        
+
         Get the block's OLX
         """
         key = LibraryUsageLocatorV2.from_string(usage_key_str)
-        version = request.query_params.get('version', None)
-
-        # Use the default `LatestVersion.AUTO` if `version` is None
-        version = xblock_api.string_to_version(version)
-
         api.require_permission_for_library_key(key.lib_key, request.user, permissions.CAN_VIEW_THIS_CONTENT_LIBRARY)
-        xml_str = xblock_api.get_block_olx(key, request.user, version=version)
+        xml_str = xblock_api.get_block_draft_olx(key)
         return Response(LibraryXBlockOlxSerializer({"olx": xml_str}).data)
 
     @convert_exceptions
diff --git a/openedx/core/djangoapps/xblock/rest_api/serializers.py b/openedx/core/djangoapps/xblock/rest_api/serializers.py
index c5971f0895d7..bb4dd1da229f 100644
--- a/openedx/core/djangoapps/xblock/rest_api/serializers.py
+++ b/openedx/core/djangoapps/xblock/rest_api/serializers.py
@@ -3,6 +3,7 @@
 """
 from rest_framework import serializers
 
+
 class XBlockOlxSerializer(serializers.Serializer):
     """
     Serializer for representing an XBlock's OLX
diff --git a/openedx/core/djangoapps/xblock/rest_api/urls.py b/openedx/core/djangoapps/xblock/rest_api/urls.py
index 1ed169b4a525..a83d5104e570 100644
--- a/openedx/core/djangoapps/xblock/rest_api/urls.py
+++ b/openedx/core/djangoapps/xblock/rest_api/urls.py
@@ -20,7 +20,7 @@
     # get/post full json fields of an XBlock:
     path('fields/', views.BlockFieldsView.as_view()),
     # Get the OLX source code of the specified block
-    path('fields/olx/', views.get_block_olx_view),
+    path('olx/', views.get_block_olx_view),
     # render one of this XBlock's views (e.g. student_view)
     path('view/<str:view_name>/', views.render_block_view),
     # get the URL needed to call this XBlock's handlers
diff --git a/openedx/core/djangoapps/xblock/rest_api/views.py b/openedx/core/djangoapps/xblock/rest_api/views.py
index 6e709b9cef19..edcbf22e0d3d 100644
--- a/openedx/core/djangoapps/xblock/rest_api/views.py
+++ b/openedx/core/djangoapps/xblock/rest_api/views.py
@@ -222,6 +222,9 @@ def get_block_olx_view(
     usage_key: UsageKeyV2,
     version: LatestVersion | int = LatestVersion.AUTO,
 ):
+    """
+    Get the OLX (XML serialization) of the specified XBlock
+    """
     context_impl = get_learning_context_impl(usage_key)
     if not context_impl.can_view_block_for_editing(request.user, usage_key):
         raise PermissionDenied(f"You don't have permission to access the OLX of component '{usage_key}'.")
diff --git a/openedx/core/djangoapps/xblock/utils.py b/openedx/core/djangoapps/xblock/utils.py
index 882037c6b3b1..01487417df63 100644
--- a/openedx/core/djangoapps/xblock/utils.py
+++ b/openedx/core/djangoapps/xblock/utils.py
@@ -15,6 +15,7 @@
 
 from .data import AuthoredDataMode, LatestVersion
 
+
 def get_secure_token_for_xblock_handler(user_id, block_key_str, time_idx=0):
     """
     Get a secure token (one-way hash) used to authenticate XBlock handler
@@ -94,7 +95,7 @@ def get_secure_token_for_xblock_handler(user_id, block_key_str, time_idx=0):
     return _get_secure_token_for_xblock_handler(user_id, block_key_str, time_idx, hashing_key)
 
 
-def _get_secure_token_for_xblock_handler(user_id, block_key_str, time_idx: int, hashing_key: str):
+def _get_secuversionre_token_for_xblock_handler(user_id, block_key_str, time_idx: int, hashing_key: str):
     """
     Internal function to extract repeating hashing steps which we
     call multiple times with different time_idx and hashing key.
@@ -177,7 +178,7 @@ def get_auto_latest_version(version: int | LatestVersion) -> int | LatestVersion
     Gets the actual LatestVersion if is `LatestVersion.AUTO`;
     otherwise, returns the same value.
     """
-    authored_data_mode = get_xblock_app_config().get_runtime_params()["authored_data_mode"]
     if version == LatestVersion.AUTO:
+        authored_data_mode = get_xblock_app_config().get_runtime_params()["authored_data_mode"]
         version = LatestVersion.DRAFT if authored_data_mode == AuthoredDataMode.DEFAULT_DRAFT else LatestVersion.PUBLISHED
-    return version
\ No newline at end of file
+    return version

From b39dfa60261360fd99e6de69ad3c4cbe9e746ae2 Mon Sep 17 00:00:00 2001
From: XnpioChV <xnpiochv@gmail.com>
Date: Fri, 29 Nov 2024 22:23:38 -0500
Subject: [PATCH 6/8] style: Fix lint

---
 openedx/core/djangoapps/content_libraries/tests/base.py | 4 ++--
 openedx/core/djangoapps/xblock/utils.py                 | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/openedx/core/djangoapps/content_libraries/tests/base.py b/openedx/core/djangoapps/content_libraries/tests/base.py
index f76d4a80dd3f..638c053f62c3 100644
--- a/openedx/core/djangoapps/content_libraries/tests/base.py
+++ b/openedx/core/djangoapps/content_libraries/tests/base.py
@@ -242,9 +242,9 @@ def _delete_library_block(self, block_key, expect_response=200):
         """ Delete a specific block from the library """
         self._api('delete', URL_LIB_BLOCK.format(block_key=block_key), None, expect_response)
 
-    def _get_library_block_olx(self, block_key, version="draft", expect_response=200):
+    def _get_library_block_olx(self, block_key, expect_response=200):
         """ Get the OLX of a specific block in the library """
-        result = self._api('get', URL_LIB_BLOCK_OLX.format(block_key=block_key), {"version": version}, expect_response)
+        result = self._api('get', URL_LIB_BLOCK_OLX.format(block_key=block_key), None, expect_response)
         if expect_response == 200:
             return result["olx"]
         return result
diff --git a/openedx/core/djangoapps/xblock/utils.py b/openedx/core/djangoapps/xblock/utils.py
index 01487417df63..b3074263554c 100644
--- a/openedx/core/djangoapps/xblock/utils.py
+++ b/openedx/core/djangoapps/xblock/utils.py
@@ -95,7 +95,7 @@ def get_secure_token_for_xblock_handler(user_id, block_key_str, time_idx=0):
     return _get_secure_token_for_xblock_handler(user_id, block_key_str, time_idx, hashing_key)
 
 
-def _get_secuversionre_token_for_xblock_handler(user_id, block_key_str, time_idx: int, hashing_key: str):
+def _get_secure_token_for_xblock_handler(user_id, block_key_str, time_idx: int, hashing_key: str):
     """
     Internal function to extract repeating hashing steps which we
     call multiple times with different time_idx and hashing key.

From 401098a27ce9e98216a0af60bc30e1105bd34eef Mon Sep 17 00:00:00 2001
From: XnpioChV <xnpiochv@gmail.com>
Date: Fri, 29 Nov 2024 22:42:37 -0500
Subject: [PATCH 7/8] style: Fix python lint

---
 openedx/core/djangoapps/xblock/utils.py | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/openedx/core/djangoapps/xblock/utils.py b/openedx/core/djangoapps/xblock/utils.py
index b3074263554c..b4ae054cf498 100644
--- a/openedx/core/djangoapps/xblock/utils.py
+++ b/openedx/core/djangoapps/xblock/utils.py
@@ -180,5 +180,9 @@ def get_auto_latest_version(version: int | LatestVersion) -> int | LatestVersion
     """
     if version == LatestVersion.AUTO:
         authored_data_mode = get_xblock_app_config().get_runtime_params()["authored_data_mode"]
-        version = LatestVersion.DRAFT if authored_data_mode == AuthoredDataMode.DEFAULT_DRAFT else LatestVersion.PUBLISHED
+        version = (
+            LatestVersion.DRAFT
+            if authored_data_mode == AuthoredDataMode.DEFAULT_DRAFT
+            else LatestVersion.PUBLISHED
+        )
     return version

From 6eaa7ffcd7d1723006ee66a8d010634762b77fcc Mon Sep 17 00:00:00 2001
From: XnpioChV <xnpiochv@gmail.com>
Date: Tue, 3 Dec 2024 18:29:51 -0500
Subject: [PATCH 8/8] style: string_to_version removed

---
 openedx/core/djangoapps/xblock/api.py | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/openedx/core/djangoapps/xblock/api.py b/openedx/core/djangoapps/xblock/api.py
index a6f37dbd432e..35c05cd7b407 100644
--- a/openedx/core/djangoapps/xblock/api.py
+++ b/openedx/core/djangoapps/xblock/api.py
@@ -330,8 +330,3 @@ def get_handler_url(
     # can be called by the XBlock from python as well and in that case we don't
     # have access to the request.
     return site_root_url + path
-
-
-def string_to_version(version: str | None) -> LatestVersion | int:
-    """ Convert from string to LatestVersion or integer version spec """
-    return VersionConverter().to_python(version)