diff --git a/remotespark/wrapperkernel/codetransformers.py b/remotespark/wrapperkernel/codetransformers.py
index 41136ad..1cec56a 100644
--- a/remotespark/wrapperkernel/codetransformers.py
+++ b/remotespark/wrapperkernel/codetransformers.py
@@ -157,3 +157,14 @@ class LogsTransformer(UserCodeTransformerBase):
             code_to_run = "print('No logs yet.')"
 
         return code_to_run, error_to_show, begin_action, end_action, deletes_session
+
+
+class PythonTransformer(UserCodeTransformerBase):
+    def get_code_to_execute(self, session_started, connection_string, force, output_var, command):
+        error_to_show = None
+        code_to_run = command
+        begin_action = Constants.do_nothing_action
+        end_action = Constants.do_nothing_action
+        deletes_session = False
+
+        return code_to_run, error_to_show, begin_action, end_action, deletes_session
diff --git a/remotespark/wrapperkernel/sparkkernelbase.py b/remotespark/wrapperkernel/sparkkernelbase.py
index 60afcd6..583ed66 100644
--- a/remotespark/wrapperkernel/sparkkernelbase.py
+++ b/remotespark/wrapperkernel/sparkkernelbase.py
@@ -125,6 +125,8 @@ class SparkKernelBase(IPythonKernel):
             return CleanUpTransformer(subcommand)
         elif subcommand == UserCommandParser.logs_command:
             return LogsTransformer(subcommand)
+        elif subcommand == UserCommandParser.local_command:
+            return PythonTransformer(subcommand)
         else:
             return NotSupportedTransformer(subcommand)
 
diff --git a/remotespark/wrapperkernel/usercommandparser.py b/remotespark/wrapperkernel/usercommandparser.py
index 378fb5a..538f8ff 100644
--- a/remotespark/wrapperkernel/usercommandparser.py
+++ b/remotespark/wrapperkernel/usercommandparser.py
@@ -12,6 +12,7 @@ class UserCommandParser(object):
     delete_command = "delete"
     clean_up_command = "cleanup"
     logs_command = "logs"
+    local_command = "local"
 
     def __init__(self):
         """Code can have a magic or no magic specified (specified with %word sign). If no magic is specified, %run will

Expose %python for wrapper kernels
So that user can execute custom python code, maybe in conjunction with -o for %sql results.
diff --git a/tests/test_codetransformers.py b/tests/test_codetransformers.py
index c03390e..698a763 100644
--- a/tests/test_codetransformers.py
+++ b/tests/test_codetransformers.py
@@ -227,3 +227,17 @@ def test_logs_transformer_no_session():
     assert_equals(begin_action, Constants.do_nothing_action)
     assert_equals(end_action, Constants.do_nothing_action)
     assert_equals(deletes_session, False)
+
+
+@with_setup(_setup, _teardown)
+def test_python_transformer():
+    transformer = PythonTransformer("command")
+
+    code_to_run, error_to_show, begin_action, end_action, deletes_session = \
+        transformer.get_code_to_execute(False, conn, False, None, code)
+
+    assert_equals(code, code_to_run)
+    assert error_to_show is None
+    assert_equals(begin_action, Constants.do_nothing_action)
+    assert_equals(end_action, Constants.do_nothing_action)
+    assert_equals(deletes_session, False)
diff --git a/tests/test_sparkkernelbase.py b/tests/test_sparkkernelbase.py
index b5e2e8f..4ec7916 100644
--- a/tests/test_sparkkernelbase.py
+++ b/tests/test_sparkkernelbase.py
@@ -129,6 +129,7 @@ def test_returns_right_transformer():
     assert type(kernel._get_code_transformer(UserCommandParser.clean_up_command)) is CleanUpTransformer
     assert type(kernel._get_code_transformer(UserCommandParser.logs_command)) is LogsTransformer
     assert type(kernel._get_code_transformer("whatever")) is NotSupportedTransformer
+    assert type(kernel._get_code_transformer(UserCommandParser.local_command)) is PythonTransformer
 
 
 @with_setup(_setup, _teardown)

pip install -e .
parse_log_pytest
requirements.txt
nose pytest
mkdir ~/.sparkmagic cp remotespark/default_config.json ~/.sparkmagic/config.json
3.7
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
anyio==3.7.1
argon2-cffi==23.1.0
argon2-cffi-bindings==21.2.0
attrs==24.2.0
beautifulsoup4==4.13.3
bleach==6.0.0
certifi @ file:///croot/certifi_1671487769961/work/certifi
cffi==1.15.1
charset-normalizer==3.4.1
comm==0.1.4
decorator==5.1.1
defusedxml==0.7.1
entrypoints==0.4
exceptiongroup==1.2.2
fastjsonschema==2.21.1
idna==3.10
importlib-metadata==6.7.0
importlib-resources==5.12.0
iniconfig==2.0.0
ipykernel==4.2.2
ipython==4.0.2
ipython-genutils==0.2.0
ipywidgets==7.8.5
Jinja2==3.1.6
jsonschema==4.17.3
jupyter-server==1.24.0
jupyter_client==7.4.9
jupyter_core==4.12.0
jupyterlab-pygments==0.2.2
jupyterlab_widgets==1.1.11
MarkupSafe==2.1.5
mistune==3.0.2
mock==5.2.0
nbclassic==1.2.0
nbclient==0.7.4
nbconvert==7.6.0
nbformat==5.8.0
nest-asyncio==1.6.0
nose==1.3.7
notebook==6.5.7
notebook_shim==0.2.4
numpy==1.21.6
packaging==24.0
pandas==1.3.5
pandocfilters==1.5.1
pexpect==4.9.0
pickleshare==0.7.5
pkgutil_resolve_name==1.3.10
plotly==1.9.4
pluggy==1.2.0
prometheus-client==0.17.1
ptyprocess==0.7.0
pycparser==2.21
Pygments==2.17.2
pyrsistent==0.19.3
pytest==7.4.4
python-dateutil==2.9.0.post0
pytz==2025.2
pyzmq==26.2.1
-e git+https://github.com/jupyter-incubator/sparkmagic.git@c3fd225a599345175240d8e96673102aacf3f624#egg=remotespark
requests==2.31.0
Send2Trash==1.8.3
simplegeneric==0.8.1
six==1.17.0
sniffio==1.3.1
soupsieve==2.4.1
terminado==0.17.1
tinycss2==1.2.1
tomli==2.0.1
tornado==6.2
traitlets==5.9.0
typing_extensions==4.7.1
urllib3==2.0.7
webencodings==0.5.1
websocket-client==1.6.1
widgetsnbextension==3.6.10
zipp==3.15.0

name: sparkmagic
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2022.12.7=py37h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - anyio==3.7.1
      - argon2-cffi==23.1.0
      - argon2-cffi-bindings==21.2.0
      - attrs==24.2.0
      - beautifulsoup4==4.13.3
      - bleach==6.0.0
      - cffi==1.15.1
      - charset-normalizer==3.4.1
      - comm==0.1.4
      - decorator==5.1.1
      - defusedxml==0.7.1
      - entrypoints==0.4
      - exceptiongroup==1.2.2
      - fastjsonschema==2.21.1
      - idna==3.10
      - importlib-metadata==6.7.0
      - importlib-resources==5.12.0
      - iniconfig==2.0.0
      - ipykernel==4.2.2
      - ipython==4.0.2
      - ipython-genutils==0.2.0
      - ipywidgets==7.8.5
      - jinja2==3.1.6
      - jsonschema==4.17.3
      - jupyter-client==7.4.9
      - jupyter-core==4.12.0
      - jupyter-server==1.24.0
      - jupyterlab-pygments==0.2.2
      - jupyterlab-widgets==1.1.11
      - markupsafe==2.1.5
      - mistune==3.0.2
      - mock==5.2.0
      - nbclassic==1.2.0
      - nbclient==0.7.4
      - nbconvert==7.6.0
      - nbformat==5.8.0
      - nest-asyncio==1.6.0
      - nose==1.3.7
      - notebook==6.5.7
      - notebook-shim==0.2.4
      - numpy==1.21.6
      - packaging==24.0
      - pandas==1.3.5
      - pandocfilters==1.5.1
      - pexpect==4.9.0
      - pickleshare==0.7.5
      - pkgutil-resolve-name==1.3.10
      - plotly==1.9.4
      - pluggy==1.2.0
      - prometheus-client==0.17.1
      - ptyprocess==0.7.0
      - pycparser==2.21
      - pygments==2.17.2
      - pyrsistent==0.19.3
      - pytest==7.4.4
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - pyzmq==26.2.1
      - requests==2.31.0
      - send2trash==1.8.3
      - simplegeneric==0.8.1
      - six==1.17.0
      - sniffio==1.3.1
      - soupsieve==2.4.1
      - terminado==0.17.1
      - tinycss2==1.2.1
      - tomli==2.0.1
      - tornado==6.2
      - traitlets==5.9.0
      - typing-extensions==4.7.1
      - urllib3==2.0.7
      - webencodings==0.5.1
      - websocket-client==1.6.1
      - widgetsnbextension==3.6.10
      - zipp==3.15.0
prefix: /opt/conda/envs/sparkmagic

tests/test_codetransformers.py::test_python_transformer tests/test_sparkkernelbase.py::test_returns_right_transformer
tests/test_codetransformers.py::test_not_supported_transformer tests/test_codetransformers.py::test_config_transformer_no_session tests/test_codetransformers.py::test_config_transformer_session_no_flag tests/test_codetransformers.py::test_config_transformer_session_flag tests/test_codetransformers.py::test_spark_transformer tests/test_codetransformers.py::test_sql_transformer tests/test_codetransformers.py::test_sql_transformer_output_var tests/test_codetransformers.py::test_hive_transformer tests/test_codetransformers.py::test_info_transformer tests/test_codetransformers.py::test_delete_transformer_no_force tests/test_codetransformers.py::test_delete_transformer_force tests/test_codetransformers.py::test_cleanup_transformer_no_force tests/test_codetransformers.py::test_cleanup_transformer_force tests/test_codetransformers.py::test_logs_transformer_session tests/test_codetransformers.py::test_logs_transformer_no_session tests/test_sparkkernelbase.py::test_get_config tests/test_sparkkernelbase.py::test_get_config_not_set tests/test_sparkkernelbase.py::test_get_config_not_set_empty_strings tests/test_sparkkernelbase.py::test_initialize_magics tests/test_sparkkernelbase.py::test_start_session tests/test_sparkkernelbase.py::test_delete_session tests/test_sparkkernelbase.py::test_instructions_from_parser_are_passed_to_transformer tests/test_sparkkernelbase.py::test_instructions_from_transformer_are_executed_code tests/test_sparkkernelbase.py::test_instructions_from_transformer_are_executed_error tests/test_sparkkernelbase.py::test_instructions_from_transformer_are_executed_deletes_session tests/test_sparkkernelbase.py::test_instructions_from_transformer_are_executed_begin_start tests/test_sparkkernelbase.py::test_instructions_from_transformer_are_executed_begin_delete tests/test_sparkkernelbase.py::test_instructions_from_transformer_are_executed_end_start tests/test_sparkkernelbase.py::test_instructions_from_transformer_are_executed_end_delete tests/test_sparkkernelbase.py::test_instructions_from_transformer_are_executed_begin_start_end_delete tests/test_sparkkernelbase.py::test_execute_throws_if_fatal_error_happened tests/test_sparkkernelbase.py::test_execute_throws_if_fatal_error_happens_for_execution tests/test_sparkkernelbase.py::test_shutdown_cleans_up tests/test_sparkkernelbase.py::test_register_auto_viz
remotespark/wrapperkernel/codetransformers.py remotespark/wrapperkernel/usercommandparser.py remotespark/wrapperkernel/sparkkernelbase.py
remotespark/wrapperkernel/codetransformers.py remotespark/wrapperkernel/usercommandparser.py remotespark/wrapperkernel/sparkkernelbase.py