Can I achieve something similar using Zrok instead of Ngrok? Possible?

is it possible to do something like this but using Zrok?

code for ngrok:
import os
from pyngrok import ngrok
from IPython.display import clear_output, Javascript
ngrok.kill()
%cd /kaggle/working/program_ml
os.system(f"filebrowser -r /kaggle -p 9876 > /dev/null 2>&1 &")
clear_output()
%load_ext tensorboard
%tensorboard --logdir logs --port 8077
p_tunnel = ngrok.connect(6969)
t_tunnel = ngrok.connect(8077)
f_tunnel = ngrok.connect(9876)
clear_output()
print("Applio Url:", p_tunnel.public_url)
print("Tensorboard Url:", t_tunnel.public_url)
print("File Url:", f_tunnel.public_url)
print("Save the link for later, this will take a while...")

!source /kaggle/tmp/.venv/bin/activate; python app.py

currently I am using this to run zrok:
command = 'source /kaggle/tmp/.venv/bin/activate; python app.py'
port = '6969'
port_t = '8077'
port_f = '9876'

------------------------

os.system(f"filebrowser -r /kaggle -p 9876 > /dev/null 2>&1 &")
%load_ext tensorboard
%tensorboard --logdir logs --port 8077
cmd = f'/kaggle/working/zrok/zrok share public http://localhost:{port} --headless & /kaggle/working/zrok/zrok share public http://localhost:{port_t} --headless & {command}'
get_ipython().system(cmd)

My question is:

  • Is there a better or more streamlined way to replicate what I'm doing with Ngrok but using Zrok instead?
  • Are there any improvements I can make to this code to achieve similar functionality more efficiently?
1 Like

The ngrok.connect function is replicating (in code) what the zrok share public command is doing. Unfortunately the zrok SDK does not (currently) have a single function you can call like that (from Python) to instantiate the reverse proxy in code.

To do the equivalent of ngrok.connect for zrok, you would need to call zrok.share.CreateShare and also open a network connection to the local resource. With those 2 network connections created (one to the zrok network, and another to the local resource), you would need to use 2 threads to read from one and write to the other, and then also the inverse (read from the other and write to the first).

There's an example in the Python SDK that shows how CreateShare and zrok.listener works:

At some point in the future we can probably provide a single function call that can instantiate a full reverse proxy in Python code.

1 Like

There's a new proxy package for the Py SDK coming in the next zrok release. It enables a Jupyter notebook to proxy a public or private share to a local target like this:

# %%
! pip install zrok

# %%

import zrok
from zrok.proxy import ProxyShare


# %%

target_url = "http://127.0.0.1:8000/"
unique_name = "myuniquename"  # a name to reuse each run or 'None' for random
share_mode = "public"         # "public" or "private"
frontend = "public"           # custom domain frontend or "public"

if unique_name.lower() == "none":
    unique_name = None


# %%

zrok_env = zrok.environment.root.Load()  # Load the environment from ~/.zrok

proxy_share = ProxyShare.create(
    root=zrok_env,
    target=target_url,
    frontends=[frontend],
    share_mode=share_mode,
    unique_name=unique_name,
    verify_ssl=True                     # Set 'False' to skip SSL verification
)


# %%

if share_mode == "public":
    print(f"Access proxy at: {', '.join(proxy_share.endpoints)}")
elif share_mode == "private":
    print(f"Run a private access frontend: 'zrok access private {proxy_share.token}'")

proxy_share.run()

Link to proxy notebook example: zrok/sdk/python/examples/proxy/proxy.ipynb at main · openziti/zrok · GitHub

Basic usage excerpt from the proxy README:

from zrok.proxy import ProxyShare
import zrok

# Load the environment
root = zrok.environment.root.Load()

# Create a temporary proxy share (will be cleaned up on exit)
proxy = ProxyShare.create(root=root, target="http://my-target-service")

# print the public URL
print(f"Access proxy at: {proxy.endpoints}")
proxy.run()

wow, this seems amazing! Is there any way to use it now?

1 Like

It just dropped. Will you let me know how it works for you?

pip install zrok==0.4.47

tried the code but got this:

---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
<ipython-input-19-d49b02e43cb2> in <cell line: 2>()
      1 #
----> 2 zrok_env = zrok.environment.root.Load()  # Load the environment from ~/.zrok
      3 
      4 proxy_share = ProxyShare.create(
      5     root=zrok_env,

/usr/local/lib/python3.10/dist-packages/zrok/environment/root.py in Load()
    112     if __rootExists():
    113         r.meta = __loadMetadata()
--> 114         r.cfg = __loadConfig()
    115         r.env = __loadEnvironment()
    116     else:

/usr/local/lib/python3.10/dist-packages/zrok/environment/root.py in __loadConfig()
    137 def __loadConfig() -> Config:
    138     cf = configFile()
--> 139     with open(cf) as f:
    140         data = json.load(f)
    141         return Config(

FileNotFoundError: [Errno 2] No such file or directory: '/root/.zrok/config.json'

I am using it on a kaggle notebook

The Load() function loads your existing zrok user environment from ~/.zrok (or Windows equivalent) that you enabled on this device: Getting Started | Zrok

The error indicates it was unable to find the config.json file in your environment, so it's possible you need to enable a zrok user environment or perhaps there is a bug requiring a config.json file when it might not exist.

EDIT: I found the issue. The SDK requires a config.json file to exist, but it should not require it, only loading it if it exists. Workaround is to create the file by setting at least one configuration directive.

This will set the same value as the default, so it will not change behavior if you are missing a config.json file inside your enabled zrok user environment dir, e.g., ~/.zrok.

zrok config set apiEndpoint https://api.zrok.io

after trying a lot I am not able to run it using the way you mentioned if possible may you write a code that can work in kaggle/colab notebook so share ports like 8188 and sometimes able to share multiple ports. that would be so helpful

Sure thing, glad to help. Please help me understand the problem you encountered.

For example, if you are running a local webserver on 8188/TCP you can do this after you set at least one configuration with zrok config set.

from zrok.proxy import ProxyShare
import zrok

# Load the environment
root = zrok.environment.root.Load()

# Create a temporary proxy share (will be cleaned up on exit)
proxy = ProxyShare.create(root=root, target="http://127.0.0.1:8188")

# print the public URL
print(f"Access proxy at: {proxy.endpoints}")
proxy.run()

The odd thing is when I install zrok using this command:
pip install zrok==0.4.47

then when I try to run this command:
zrok config set apiEndpoint https://api.zrok.io

I got this error:
/bin/bash: line 1: Zrok: command not found

do I have to install the Zrok installation file?

so the problem was I need to install the zrok_0.4.47_linux_amd64.tar.gz and now the things are working as it supposed too, thank you so much

1 Like

You needed to install the zrok executable so you could zrok enable, correct?

yes, I did zrok enable token and I got the shared URL but it is not loading, keep scrolling, its been 2 days but no solution. I am sharing all the zrok code I am using on kaggle notebook:

!pip install zrok==0.4.47
!pip install waitress
!mkdir -p /kaggle/working/zrok
%cd /kaggle/working/zrok
!wget https://github.com/openziti/zrok/releases/download/v0.4.47/zrok_0.4.47_linux_amd64.tar.gz
!tar -xvf ./zrok*.gz  
!chmod a+x /kaggle/working/zrok/zrok

#set the endpoint to work
!/kaggle/working/zrok/zrok config set apiEndpoint https://api.zrok.io

# Enable zrok with your token
token = "my_secret_token"
!/kaggle/working/zrok/zrok enable $token

from  zrok.proxy import ProxyShare
import zrok

# Load the environment
root = zrok.environment.root.Load()

# Create a temporary proxy share (will be cleaned up on exit)
proxy = ProxyShare.create(root=root, target="http://127.0.0.1:8188")

# print the public URL
print(f"Access proxy at: {proxy.endpoints}")
proxy.run()

it is giving me share URL but nothing is loading and no error so far. but if I use:
!kaggle/working/zrok/zrok share public [http://localhost](http://localhost/):{port} --headless

then I got the URL and it works but not the one you suggested. please help.

I signed up for Kaggle to see how it works. Is your goal to proxy to a local webserver like http://127.0.0.1:8188 that is provided by a previous cell in the same notebook, a different notebook, or some other background service?

I'm very new at Kaggle, and I had trouble running the first commands in your example, e.g. pip install waitress. I tried the default simple index and pypi index but I keep getting a timeout. It's as if my Kaggle instance can't reach the internet to install from PyPi. After some forum diving, I suspect internet-enabled kernels are disabled for brand-new Kaggle users.

Another option, if the webserver you're sharing with zrok happens to be a Python application in the same notebook, you can bypass the proxy entirely by modifying your Python webserver to use the zrok SDK directly, like this: The Python zrok SDK and zrok/sdk/python/examples/http-server at main · openziti/zrok · GitHub

EDIT: I finally found a "session options" toggle for the internet access in the sidebar. It's disabled with tooltip: "Your account must be phone verified to access the internet."

After I learned how to enable internet access for my Kaggle kernel, I was able to use zrok's ProxyShare by following your example and making some modifications while I was troubleshooting and learning to use Kaggle.

Here's the public share link for my Kaggle notebook with example output: zrok-proxy-share | Kaggle

Still, the state of the Kaggle notebook was not clear to me at all times, and I found it helpful to run the cells individually in sequence.