feat: python v3.13

added python v3.13 with uv. Tried to optimize the Image size.
diff --git a/.github/workflows/image.yaml b/.github/workflows/image.yaml
index d25374c..96e8cab 100644
--- a/.github/workflows/image.yaml
+++ b/.github/workflows/image.yaml
@@ -101,7 +101,7 @@
       strategy:
         max-parallel: 1
         matrix:
-          version: [v3.10,v3.11,v3.12]      
+          version: [v3.10,v3.11,v3.12,v3.13]      
       steps:
         - name: Checkout recursive
           uses: actions/checkout@v2
diff --git a/runtime/python/v3.13/Dockerfile b/runtime/python/v3.13/Dockerfile
new file mode 100644
index 0000000..25a915c
--- /dev/null
+++ b/runtime/python/v3.13/Dockerfile
@@ -0,0 +1,70 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+ARG COMMON=missing:missing
+FROM ${COMMON} AS builder
+
+FROM python:3.13.4-slim-bookworm AS build-env
+
+# Set environment for uv installation
+ENV UV_CACHE_DIR=/tmp/uv-cache \
+    UV_INSTALL_DIR=/usr/local/bin
+
+# Install build tools and install uv
+RUN apt-get update && apt-get install -y --no-install-recommends \
+    curl ca-certificates build-essential python3-dev && \
+    curl -LsSf https://astral.sh/uv/install.sh | sh && \
+    apt-get purge -y curl && \
+    rm -rf /var/lib/apt/lists/*
+
+# Install Python dependencies
+WORKDIR /build
+COPY requirements.txt .
+RUN uv pip install --python python3 --system six wheel virtualenv
+RUN uv pip install --python python3 --system --no-cache-dir -r requirements.txt
+
+# Final minimal runtime
+FROM python:3.13.4-slim-bookworm
+
+# Set runtime environment
+ENV OW_EXECUTION_ENV=apacheopenserverless/runtime-python-v3.13.4 \
+    HOME=/tmp \
+    OW_LOG_INIT_ERROR=1 \
+    OW_WAIT_FOR_ACK=1 \
+    OW_COMPILER=/bin/compile
+
+# Install only runtime deps
+RUN apt-get update && apt-get install -y --no-install-recommends \
+    python3-psycopg2 zip xpdf ca-certificates && \
+    apt-get autoremove -y && \
+    rm -rf /var/lib/apt/lists/*
+
+# Copy uv binary and Python packages from builder
+COPY --from=build-env /usr/local/bin/uv /usr/local/bin/uvx /usr/local/bin/
+COPY --from=build-env /usr/local/lib/python3.13 /usr/local/lib/python3.13
+
+# Copy OpenWhisk runtime and proxy binary
+COPY --from=builder /go/bin/proxy /bin/proxy
+ADD bin/compile /bin/compile
+ADD lib/launcher.py /lib/launcher.py
+
+# Prepare /action
+WORKDIR /action
+RUN chown nobody:root /action && chmod 0775 /action
+
+USER nobody
+ENTRYPOINT ["/bin/proxy"]
diff --git a/runtime/python/v3.13/bin/compile b/runtime/python/v3.13/bin/compile
new file mode 100755
index 0000000..a85d56e
--- /dev/null
+++ b/runtime/python/v3.13/bin/compile
@@ -0,0 +1,140 @@
+#!/usr/bin/env python3
+"""Python Action Builder
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+"""
+
+from __future__ import print_function
+import os, os.path, sys, ast, shutil, subprocess, traceback
+import importlib, virtualenv
+from os.path import abspath, exists, dirname
+
+# write a file creating intermediate directories
+def write_file(file, body, executable=False):
+    try: os.makedirs(dirname(file), mode=0o755)
+    except: pass
+    with open(file, mode="wb") as f:
+        f.write(body.encode("utf-8"))
+    if executable:
+        os.chmod(file, 0o755)
+
+# copy a file eventually replacing a substring
+def copy_replace(src, dst, match=None, replacement=""):
+    with open(src, 'rb') as s:
+        body = s.read()
+        if match:
+            body = body.decode("utf-8").replace(match, replacement)
+        write_file(dst, body)
+
+# assemble sources
+def sources(launcher, main, src_dir):
+    # move exec in the right place if exists
+    src_file = "%s/exec" % src_dir
+    if exists(src_file):
+        os.rename(src_file, "%s/__main__.py" % src_dir)
+    if exists("%s/__main__.py" % src_dir):
+        os.rename("%s/__main__.py" % src_dir, "%s/main__.py" % src_dir)
+
+    # write the boilerplate in a temp dir
+    copy_replace(launcher, "%s/exec__.py" % src_dir,
+          "from main__ import main as main",
+          "from main__ import %s as main" % main )
+
+# build virtualenv if there is a requirements.txt
+def virtualenv(tgt_dir):
+    # check virtualenv
+    virtualenv_dir = abspath('%s/virtualenv' % tgt_dir)
+    requirements_txt = abspath("%s/requirements.txt" % tgt_dir)
+    if exists(requirements_txt):
+        if not os.path.isdir(virtualenv_dir):
+            cmd = "python -m virtualenv %s >/tmp/err 2>/tmp/err" % virtualenv_dir
+            if os.system(cmd) != 0:
+                with open("/tmp/err", "r") as f:
+                    sys.stderr.write(f.read())
+            else:
+                cmd = ". %s/bin/activate && python -m pip install -r %s >/tmp/err 2>/tmp/err" % (virtualenv_dir, requirements_txt)
+                if os.system(cmd) != 0:
+                    with open("/tmp/err", "r") as f:
+                        sys.stderr.write(f.read())
+    sys.stderr.flush()
+
+# compile sources
+def build(src_dir, tgt_dir):
+    # in general, compile your program into an executable format
+    # for scripting languages, move sources and create a launcher
+    # move away the action dir and replace with the new
+    shutil.rmtree(tgt_dir)
+    shutil.move(src_dir, tgt_dir)
+    tgt_file = "%s/exec" % tgt_dir
+    write_file(tgt_file, """#!/bin/bash
+export PYTHONIOENCODING=UTF-8
+if [[ "$__OW_EXECUTION_ENV" == "" || "$(cat $0.env)" == "$__OW_EXECUTION_ENV" ]]
+then cd "$(dirname $0)"
+     exec /usr/local/bin/python exec__.py "$@"
+else echo "Execution Environment Mismatch"
+     echo "Expected: $(cat $0.env)"
+     echo "Actual: $__OW_EXECUTION_ENV"
+     exit 1
+fi
+""", True)
+    if os.environ.get("__OW_EXECUTION_ENV"):
+      write_file("%s.env"%tgt_file, os.environ['__OW_EXECUTION_ENV'])
+    return tgt_file
+
+#check if a module exists
+def check(tgt_dir, module_name):
+    # activate virtualenv if any
+    path_to_virtualenv = abspath('%s/virtualenv' % tgt_dir)
+    if os.path.isdir(path_to_virtualenv):
+        activate_this_file = path_to_virtualenv + '/bin/activate_this.py'
+        if not os.path.exists(activate_this_file):
+            # check if this was packaged for windows
+            activate_this_file = path_to_virtualenv + '/Scripts/activate_this.py'
+        if os.path.exists(activate_this_file):
+            with open(activate_this_file) as f:
+                code = compile(f.read(), activate_this_file, 'exec')
+                exec(code, dict(__file__=activate_this_file))
+        else:
+            sys.stderr.write("Invalid virtualenv. Zip file does not include 'activate_this.py'.\n")
+    # check module
+    try:
+        sys.path.append(tgt_dir)
+        mod = importlib.util.find_spec(module_name)
+        if mod:
+            with open(mod.origin, "rb") as f:
+                ast.parse(f.read().decode("utf-8"))
+        else:
+            sys.stderr.write("Zip file does not include %s\n" % module_name)
+    except SyntaxError as er:
+        sys.stderr.write(er.msg)
+    except Exception as ex:
+        sys.stderr.write(ex)
+    sys.stderr.flush()
+
+if __name__ == '__main__':
+    if len(sys.argv) < 4:
+        sys.stdout.write("usage: <main-function> <source-dir> <target-dir>\n")
+        sys.stdout.flush()
+        sys.exit(1)
+    launcher = "%s/lib/launcher.py" % dirname(dirname(sys.argv[0]))
+    src_dir = abspath(sys.argv[2])
+    tgt_dir = abspath(sys.argv[3])
+    sources(launcher, sys.argv[1], src_dir)
+    build(abspath(sys.argv[2]), tgt_dir)
+    check(tgt_dir, "main__")
+    sys.stdout.flush()
+    sys.stderr.flush()
diff --git a/runtime/python/v3.13/lib/launcher.py b/runtime/python/v3.13/lib/launcher.py
new file mode 100755
index 0000000..ccf0c68
--- /dev/null
+++ b/runtime/python/v3.13/lib/launcher.py
@@ -0,0 +1,73 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+from __future__ import print_function
+from sys import stdin
+from sys import stdout
+from sys import stderr
+from os import fdopen
+import sys, os, json, traceback, warnings
+
+try:
+  # if the directory 'virtualenv' is extracted out of a zip file
+  path_to_virtualenv = os.path.abspath('./virtualenv')
+  if os.path.isdir(path_to_virtualenv):
+    # activate the virtualenv using activate_this.py contained in the virtualenv
+    activate_this_file = path_to_virtualenv + '/bin/activate_this.py'
+    if not os.path.exists(activate_this_file): # try windows path
+      activate_this_file = path_to_virtualenv + '/Scripts/activate_this.py'
+    if os.path.exists(activate_this_file):
+      with open(activate_this_file) as f:
+        code = compile(f.read(), activate_this_file, 'exec')
+        exec(code, dict(__file__=activate_this_file))
+    else:
+      sys.stderr.write("Invalid virtualenv. Zip file does not include 'activate_this.py'.\n")
+      sys.exit(1)
+except Exception:
+  traceback.print_exc(file=sys.stderr, limit=0)
+  sys.exit(1)
+
+# now import the action as process input/output
+from main__ import main as main
+
+out = fdopen(3, "wb")
+if os.getenv("__OW_WAIT_FOR_ACK", "") != "":
+    out.write(json.dumps({"ok": True}, ensure_ascii=False).encode('utf-8'))
+    out.write(b'\n')
+    out.flush()
+
+env = os.environ
+while True:
+  line = stdin.readline()
+  if not line: break
+  args = json.loads(line)
+  payload = {}
+  for key in args:
+    if key == "value":
+      payload = args["value"]
+    else:
+      env["__OW_%s" % key.upper()]= args[key]
+  res = {}
+  try:
+    res = main(payload)
+  except Exception as ex:
+    print(traceback.format_exc(), file=stderr)
+    res = {"error": str(ex)}
+  out.write(json.dumps(res, ensure_ascii=False).encode('utf-8'))
+  out.write(b'\n')
+  stdout.flush()
+  stderr.flush()
+  out.flush()
diff --git a/runtime/python/v3.13/requirements.txt b/runtime/python/v3.13/requirements.txt
new file mode 100644
index 0000000..1b276e8
--- /dev/null
+++ b/runtime/python/v3.13/requirements.txt
@@ -0,0 +1,42 @@
+beautifulsoup4==4.13.4
+ollama==0.4.5
+openai==1.59.3
+pymilvus==2.5.3
+redis==5.2.1
+pillow==11.1.0
+nltk==3.8.1
+httplib2==0.19.1
+kafka_python==2.0.2
+python-dateutil==2.8.2
+requests==2.32.2
+scrapy==2.5.0
+simplejson==3.17.5
+twisted==21.7.0
+netifaces==0.11.0
+pyyaml==6.0.2
+boto3==1.35.98
+psycopg==3.1.10
+pymongo==4.4.1
+minio==7.1.16
+auth0-python==4.6.0
+langdetect==1.0.9
+plotly==5.19.0
+joblib==1.4.2
+lightgbm==4.5.0
+feedparser==6.0.11
+numpy==1.26.4
+scikit-learn==1.5.2
+langchain==0.3.14
+langchain-ollama==0.2.2
+langchain-openai==0.2.14
+langchain-anthropic==0.3.1
+langchain-together==0.2.0
+langchain-postgres==0.0.12
+langchain-milvus==0.1.7
+bcrypt==4.2.1
+chevron==0.14.0
+chess==1.11.1
+uvicorn==0.34.2
+fastapi==0.115.12
+starlette==0.46.2
+mcp==1.6.0
\ No newline at end of file
diff --git a/runtimes.json.tpl b/runtimes.json.tpl
index 88ee1db..cf13a84 100644
--- a/runtimes.json.tpl
+++ b/runtimes.json.tpl
@@ -127,6 +127,20 @@
                 }
             },
             {
+                "kind": "python:3.13",
+                "default": false,
+                "image": {
+                    "prefix": "$OPS_RUNTIME_PREFIX",
+                    "name": "openserverless-runtime-python",
+                    "tag": "$OPS_RUNTIME_TAG_PYTHON_V3_13"
+                },
+                "deprecated": false,
+                "attached": {
+                    "attachmentName": "codefile",
+                    "attachmentType": "text/plain"
+                }
+            },
+            {
                 "kind": "python:3.11ca",
                 "default": false,
                 "image": {