{"id":26093851,"url":"https://github.com/ngrok/ngrok-python","last_synced_at":"2025-04-06T16:10:20.414Z","repository":{"id":143648171,"uuid":"613552529","full_name":"ngrok/ngrok-python","owner":"ngrok","description":"Embed ngrok secure ingress into your Python apps with a single line of code.","archived":false,"fork":false,"pushed_at":"2024-08-07T17:18:22.000Z","size":2054,"stargazers_count":141,"open_issues_count":9,"forks_count":25,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-04-03T01:44:38.961Z","etag":null,"topics":["networking","ngrok","python","python3","reverse-proxy"],"latest_commit_sha":null,"homepage":"https://ngrok.com","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ngrok.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE-APACHE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-13T19:50:24.000Z","updated_at":"2025-03-26T09:43:54.000Z","dependencies_parsed_at":"2024-06-18T18:14:27.263Z","dependency_job_id":"9be8ea01-967b-4b86-8fdc-c4e620cd92a6","html_url":"https://github.com/ngrok/ngrok-python","commit_stats":null,"previous_names":["ngrok/ngrok-py"],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngrok%2Fngrok-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngrok%2Fngrok-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngrok%2Fngrok-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngrok%2Fngrok-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ngrok","download_url":"https://codeload.github.com/ngrok/ngrok-python/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247509221,"owners_count":20950232,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["networking","ngrok","python","python3","reverse-proxy"],"created_at":"2025-03-09T12:05:52.891Z","updated_at":"2025-04-06T16:10:20.387Z","avatar_url":"https://github.com/ngrok.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# Python SDK for ngrok\n\n[![PyPI][pypi-badge]][pypi-url]\n[![Supported Versions][ver-badge]][ver-url]\n[![MIT licensed][mit-badge]][mit-url]\n[![Apache-2.0 licensed][apache-badge]][apache-url]\n[![Continuous integration][ci-badge]][ci-url]\n\n[pypi-badge]: https://img.shields.io/pypi/v/ngrok\n[pypi-url]: https://pypi.org/project/ngrok\n[ver-badge]: https://img.shields.io/pypi/pyversions/ngrok.svg\n[ver-url]: https://pypi.org/project/ngrok\n[mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg\n[mit-url]: https://github.com/ngrok/ngrok-rust/blob/main/LICENSE-MIT\n[apache-badge]: https://img.shields.io/badge/license-Apache_2.0-blue.svg\n[apache-url]: https://github.com/ngrok/ngrok-rust/blob/main/LICENSE-APACHE\n[ci-badge]: https://github.com/ngrok/ngrok-python/actions/workflows/ci.yml/badge.svg\n[ci-url]: https://github.com/ngrok/ngrok-python/actions/workflows/ci.yml\n\n`ngrok-python` is the official Python SDK for ngrok that requires no binaries. Quickly enable secure production-ready connectivity to your applications and services directly from your code.\n\n[ngrok](https://ngrok.com) is a globally distributed gateway that provides secure connectivity for applications and services running in any environment.\n\n# Installation\n\nThe `ngrok-python` SDK can be installed from [PyPI](https://pypi.org/project/ngrok) via `pip`:\n\n```shell\npip install ngrok\n```\n\n# Quickstart\n\n1. [Install `ngrok-python`](#installation)\n2. Export your [authtoken from the ngrok dashboard](https://dashboard.ngrok.com/get-started/your-authtoken) as `NGROK_AUTHTOKEN` in your terminal\n3. Add the following code to your application to establish connectivity via the [forward method](https://github.com/ngrok/ngrok-python/blob/main/examples/ngrok-forward-minimal.py) through port `9000` on `localhost`:\n\n    ```python\n    # import ngrok python sdk\n    import ngrok\n    import time\n    \n    # Establish connectivity\n    listener = ngrok.forward(9000, authtoken_from_env=True)\n    \n    # Output ngrok url to console\n    print(f\"Ingress established at {listener.url()}\")\n\n    # Keep the listener alive\n    try:\n    while True:\n        time.sleep(1)\n    except KeyboardInterrupt:\n        print(\"Closing listener\")\n    ```\n\nThat's it! Your application should now be available through the url output in your terminal. \n\n\u003e **Note**\n\u003e You can find more examples in [the examples directory](https://github.com/ngrok/ngrok-python/tree/main/examples).\n\n# Documentation\n\nA full quickstart guide and API reference can be found in the [ngrok-python documentation](https://ngrok.github.io/ngrok-python/).\n\n### Authentication\n\nTo use most of ngrok's features, you'll need an authtoken. To obtain one, sign up for free at [ngrok.com](https://dashboard.ngrok.com/signup) and retrieve it from the [authtoken page in your ngrok dashboard](https://dashboard.ngrok.com/get-started/your-authtoken). Once you have copied your authtoken, you can reference it in several ways.\n\nYou can set it in the `NGROK_AUTHTOKEN` environment variable and pass `authtoken_from_env=True` to the [forward](https://ngrok.github.io/ngrok-python/module.html) method:\n\n```python\nngrok.forward(authtoken_from_env=True, ...)\n```\n\nOr pass the authtoken directly to the [forward](https://ngrok.github.io/ngrok-python/module.html) method:\n\n```python\nngrok.forward(authtoken=token, ...)\n```\n\nOr set it for all connections with the [set_auth_token](https://ngrok.github.io/ngrok-python/module.html) method:\n\n```python\nngrok.set_auth_token(token)\n```\n\n### Connection\n\nThe [forward](https://ngrok.github.io/ngrok-python/module.html) method is the easiest way to start an ngrok session and establish a listener to a specified address. If an asynchronous runtime is running, the [forward](https://ngrok.github.io/ngrok-python/module.html) method returns a promise that resolves to the public listener object.\n\nWith no arguments, the [forward](https://ngrok.github.io/ngrok-python/module.html) method will start an HTTP listener to `localhost` port `80`:\n\n```python\nlistener = ngrok.forward()\n```\n\nYou can pass the port number to forward on `localhost`:\n\n```python\nlistener = ngrok.forward(4242)\n```\n\nOr you can specify the host and port via a string:\n\n```python\nlistener = ngrok.forward(\"localhost:4242\")\n```\n\nMore options can be passed to the `forward` method to customize the connection:\n\n```python\nlistener = ngrok.forward(8080, basic_auth=\"ngrok:online1line\"})\nlistener = ngrok.forward(8080, oauth_provider=\"google\", oauth_allow_domains=\"example.com\")\n```\n\nThe second (optional) argument is the listener type, which defaults to `http`. To create a TCP listener:\n\n```python\nlistener = ngrok.forward(25565, \"tcp\")\n```\n\nSince the options are kwargs, you can also use the `**` operator to pass a dictionary for configuration:\n\n```python\noptions = {\"authtoken_from_env\":True, \"response_header_add\":\"X-Awesome:yes\"}\nlistener = ngrok.forward(8080, **options)\n```\n\nSee [Full Configuration](#full-configuration) for the list of possible configuration options.\n\n### Disconnection\n\nTo close a listener use the [disconnect](https://ngrok.github.io/ngrok-python/module.html) method with the `url` of the listener to close. If there is an asynchronous runtime running the [disconnect](https://ngrok.github.io/ngrok-python/module.html) method returns a promise that resolves when the call is complete.\n\n```python\nngrok.disconnect(url)\n```\n\nOr omit the `url` to close all listeners:\n\n```python\nngrok.disconnect()\n```\n\nThe [close](https://ngrok.github.io/ngrok-python/ngrok_listener.html) method on a listener will shut it down, and also stop the ngrok session if it is no longer needed. This method returns a promise that resolves when the listener is closed.\n\n```python\nawait listener.close()\n```\n\n### List all Listeners\n\nTo list all current non-closed listeners use the [get_listeners](https://ngrok.github.io/ngrok-python/module.html) method. If there is an asynchronous runtime running the [get_listeners](https://ngrok.github.io/ngrok-python/module.html) method returns a promise that resolves to the list of listener objects.\n\n```python\nlisteners = ngrok.get_listeners()\n```\n\n### TLS Backends\n\nAs of version `0.10.0` there is backend TLS connection support, validated by a filepath specified in the `SSL_CERT_FILE` environment variable, or falling back to the host OS installed trusted certificate authorities. So it is now possible to do this to connect:\n\n```python\nngrok.forward(\"https://127.0.0.1:3000\", authtoken_from_env=True)\n```\n\nIf the service is using certs not trusted by the OS, such as self-signed certificates, add an environment variable like this before running: `SSL_CERT_FILE=/path/to/ca.crt`. There is also a `verify_upstream_tls=False` option to disable certification verification.\n\n### Unix Sockets\n\nYou may also choose to use Unix Sockets instead of TCP. You can view an example of this [here](https://github.com/ngrok/ngrok-python/blob/main/examples/ngrok-http-full.py).\n\nA socket address may be passed directly into the listener `forward()` call as well by prefixing the address with `unix:`, for example `unix:/tmp/socket-123`.\n\n### Builders\n\nFor more control over Sessions and Listeners, the builder classes can be used.\n\nA minimal example using the builder class looks like [the following](https://github.com/ngrok/ngrok-python/blob/main/examples/ngrok-http-minimal.py):\n\n```python\nasync def create_listener():\n    session = await ngrok.NgrokSessionBuilder().authtoken_from_env().connect()\n    listener = await session.http_endpoint().listen()\n    print (f\"Ingress established at {listener.url()}\")\n    listener.forward(\"localhost:9000\")\n```\n\nSee here for a [Full Configuration Example](https://github.com/ngrok/ngrok-python/blob/main/examples/ngrok-http-full.py)\n\n### Full Configuration\n\nThis example shows [all the possible configuration items of ngrok.forward](https://github.com/ngrok/ngrok-python/blob/main/examples/ngrok-forward-full.py):\n\n```python\nlistener = ngrok.forward(\n    # session configuration\n    addr=\"localhost:8080\",\n    authtoken=\"\u003cauthtoken\u003e\",\n    authtoken_from_env=True,\n    app_protocol=\"http2\",\n    session_metadata=\"Online in One Line\",\n    # advanced session connection configuration\n    server_addr=\"example.com:443\",\n    root_cas=\"trusted\",\n    session_ca_cert=load_file(\"ca.pem\"),\n    # listener configuration\n    metadata=\"example listener metadata from python\",\n    domain=\"\u003cdomain\u003e\",\n    schemes=[\"HTTPS\"],\n    proto=\"http\",\n    proxy_proto=\"\",  # One of: \"\", \"1\", \"2\"\n    labels=\"edge:edghts_2G...\",  # Along with proto=\"labeled\"\n    # module configuration\n    basic_auth=[\"ngrok:online1line\"],\n    circuit_breaker=0.1,\n    compression=True,\n    allow_user_agent=\"^mozilla.*\",\n    deny_user_agent=\"^curl.*\",\n    allow_cidr=\"0.0.0.0/0\",\n    deny_cidr=\"10.1.1.1/32\",\n    crt=load_file(\"crt.pem\"),\n    key=load_file(\"key.pem\"),\n    mutual_tls_cas=load_file(\"ca.crt\"),\n    oauth_provider=\"google\",\n    oauth_allow_domains=[\"\u003cdomain\u003e\"],\n    oauth_allow_emails=[\"\u003cemail\u003e\"],\n    oauth_scopes=[\"\u003cscope\u003e\"],\n    oauth_client_id=\"\u003cid\u003e\",\n    oauth_client_secret=\"\u003cid\u003e\",\n    oidc_issuer_url=\"\u003curl\u003e\",\n    oidc_client_id=\"\u003cid\u003e\",\n    oidc_client_secret=\"\u003csecret\u003e\",\n    oidc_allow_domains=[\"\u003cdomain\u003e\"],\n    oidc_allow_emails=[\"\u003cemail\u003e\"],\n    oidc_scopes=[\"\u003cscope\u003e\"],\n    policy=\"\u003cpolicy_json\u003e\",\n    request_header_remove=\"X-Req-Nope\",\n    response_header_remove=\"X-Res-Nope\",\n    request_header_add=\"X-Req-Yup:true\",\n    response_header_add=\"X-Res-Yup:true\",\n    verify_upstream_tls=False,\n    verify_webhook_provider=\"twilio\",\n    verify_webhook_secret=\"asdf\",\n    websocket_tcp_converter=True,\n)\n```\n\n# ASGI Runner\n\n`ngrok-python` comes bundled with an ASGI (Asynchronous Server Gateway Interface) runner `ngrok-asgi` that can be used for Uvicorn, Gunicorn, Django and more, with no code. \n\nTo use prefix your start up command for a Uvicorn or Gunicorn web server with either `ngrok-asgi` or `python -m ngrok`. \n\nAny TCP or Unix Domain Socket arguments will be used to establish connectivity automatically. The ngrok listener can be configured using command flags, for instance adding `--basic-auth ngrok online1line` will introduce basic authentication to the ingress listener.\n\n### Uvicorn\n\n```shell\n# Basic Usage\nngrok-asgi uvicorn mysite.asgi:application\n\n# With custom host and port\nngrok-asgi uvicorn mysite.asgi:application \\\n    --host localhost \\\n    --port 1234\n\n# Using basic auth\nngrok-asgi uvicorn mysite.asgi:application \\\n    --host localhost \\\n    --port 1234 \\\n    --basic-auth ngrok online1line\n\n# Using custom sock file\nngrok-asgi uvicorn mysite.asgi:application \\\n    --uds /tmp/uvicorn.sock\n\n# Using module name\npython -m ngrok uvicorn mysite.asgi:application \\\n    --oauth-provider google \\\n    --allow-emails bob@example.com\n```\n\n### Gunicorn\n\n```shell\n# Basic Usage\nngrok-asgi gunicorn mysite.asgi:application -k uvicorn.workers.UvicornWorker\n\n# With custom host and port\nngrok-asgi gunicorn mysite.asgi:application -k uvicorn.workers.UvicornWorker \\\n    --bind localhost:1234\n\n# Using webhook verifications\nngrok-asgi gunicorn mysite.asgi:application -k uvicorn.workers.UvicornWorker \\\n    --webhook-verification twilio s3cr3t\n\n# Using custom sock file\nngrok-asgi gunicorn mysite.asgi:application -k uvicorn.workers.UvicornWorker \\\n    --bind unix:/tmp/gunicorn.sock\n\n# Using module name\npython -m ngrok gunicorn mysite.asgi:application -k uvicorn.workers.UvicornWorker --response-header X-Awesome True\n```\n\n# Examples\n\n#### Listeners\n  - [HTTP](https://github.com/ngrok/ngrok-python/tree/main/examples/ngrok-http-minimal.py)\n    - [Full Configuration Example](https://github.com/ngrok/ngrok-python/tree/main/examples/ngrok-http-full.py)\n  - [Labeled](https://github.com/ngrok/ngrok-python/tree/main/examples/ngrok-labeled.py)\n  - [TCP](https://github.com/ngrok/ngrok-python/tree/main/examples/ngrok-tcp.py)\n  - [TLS](https://github.com/ngrok/ngrok-python/tree/main/examples/ngrok-tls.py)\n\n#### Frameworks\n  - [AIOHTTP](https://github.com/ngrok/ngrok-python/tree/main/examples/aiohttp-ngrok.py)\n  - [AWS APP Runner](https://github.com/ngrok/ngrok-sdk-serverless-example)\n    - with [changes for Python](https://docs.aws.amazon.com/apprunner/latest/dg/service-source-code-python.html)\n  - Django\n    - [Single File Example](https://github.com/ngrok/ngrok-python/tree/main/examples/django-single-file.py)\n    - [Modify manage.py Example](https://github.com/ngrok/ngrok-python/tree/main/examples/djangosite/manage.py)\n    - [Modify asgi.py Example](https://github.com/ngrok/ngrok-python/tree/main/examples/djangosite/djangosite/ngrok-asgi.py)\n    - or [via `ngrok-asgi`](#asgi-runner)\n  - [Flask](https://github.com/ngrok/ngrok-python/tree/main/examples/flask-ngrok.py)\n  - [Gunicorn](#gunicorn)\n  - [Hypercorn](https://github.com/ngrok/ngrok-python/tree/main/examples/hypercorn-http2-ngrok.py)\n  - [Streamlit](https://github.com/ngrok/ngrok-python/tree/main/examples/streamlit/streamlit-ngrok.py)\n  - [Tornado](https://github.com/ngrok/ngrok-python/tree/main/examples/tornado-ngrok.py)\n  - [Uvicorn](https://github.com/ngrok/ngrok-python/tree/main/examples/uvicorn-ngrok.py)\n\n#### Machine Learning\n  - Gradio\n    - [ngrok-asgi Example](https://github.com/ngrok/ngrok-python/tree/main/examples/gradio/gradio-asgi.py)\n    - [gradio CLI Example](https://github.com/ngrok/ngrok-python/tree/main/examples/gradio/gradio-ngrok.py)\n  - [OpenPlayground](https://github.com/ngrok/ngrok-python/tree/main/examples/openplayground/run.py)\n  - [GPT4ALL](https://github.com/ngrok/ngrok-python/tree/main/examples/gpt4all/run.py)\n  - [Stable Diffusion WebUI](https://github.com/AUTOMATIC1111/stable-diffusion-webui/) by AUTOMATIC1111\n    - `ngrok-python` is now built-in, see the `--ngrok` and `--ngrok-options` arguments.\n  - [Text Generation WebUI](https://github.com/oobabooga/text-generation-webui) by oobabooga\n    - `ngrok-python` is now built-in, see the `--extension ngrok` argument.\n\n# Platform Support\n\nPre-built binaries are provided on PyPI for the following platforms:\n\n| OS         | i686 | x64 | aarch64 | arm |\n| ---------- | -----|-----|---------|-----|\n| Windows    |   ✓  |  ✓  |    *    |     |\n| MacOS      |      |  ✓  |    ✓    |     |\n| Linux      |      |  ✓  |    ✓    |  ✓  |\n| Linux musl |      |  ✓  |    ✓    |     |\n| FreeBSD    |      |  *  |         |     |\n\n\u003e **Note**\n\u003e `ngrok-python`, and [ngrok-rust](https://github.com/ngrok/ngrok-rust/) which it depends on, are open source, so it may be possible to build them for other platforms.\n\u003e - Windows-aarch64 will be supported after the next release of [Ring](https://github.com/briansmith/ring/issues/1167).\n\u003e - FreeBSD-x64 is built by the release process, but PyPI won't accept BSD flavors.\n\n# Dependencies\n\n- This project relies on [PyO3](https://pyo3.rs/), an excellent system to ease development and building of Rust plugins for Python.\n- Thank you to [OpenIoTHub](https://github.com/OpenIoTHub/ngrok) for handing over the ngrok name on PyPI.\n\n# Changelog\n\nChanges to `ngrok-python` are tracked under [CHANGELOG.md](https://github.com/ngrok/ngrok-python/blob/main/CHANGELOG.md).\n\n# Join the ngrok Community\n\n- Check out [our official docs](https://docs.ngrok.com)\n- Read about updates on [our blog](https://blog.ngrok.com)\n- Open an [issue](https://github.com/ngrok/ngrok-python/issues) or [pull request](https://github.com/ngrok/ngrok-python/pulls)\n- Join our [Slack community](https://ngrok.com/slack)\n- Follow us on [X / Twitter (@ngrokHQ)](https://twitter.com/ngrokhq)\n- Subscribe to our [Youtube channel (@ngrokHQ)](https://www.youtube.com/@ngrokhq)\n\n# License\n\nThis project is dual-licensed under [Apache, Version 2.0](LICENSE-APACHE) and [MIT](LICENSE-MIT).\nYou can choose between one of them if you use this work.\n\n### Contributions\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in `ngrok-python` by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n\n# Development: Getting Started\n\n**Prerequisites:**\n- a valid Ngrok `authtoken`\n-  `make` available in your PATH\n\n1. Update [Cargo.toml](./Cargo.toml) with the _latest supported_ ```ngrok = { version = \"=VERSION_HERE\" }``` from [ngrok-rust](https://github.com/ngrok/ngrok-rust/blob/main/ngrok/Cargo.toml#L3). `ngrok-rust` is used for the bindings in [src/rust_files_here.rs](./src)\n\n2. Run `make build` (builds the `rust` bindings / `python` dependencies)\n\n3. Happy developing!\n\n\u003cbr/\u003e\n\n**Example Commands**:\n\n_building the project_\n```shell\nmake develop\n```\n\n_running the entire test suite_\n```shell\n# running the entire test suite\nexport NGROK_AUTHTOKEN=\"YOUR_AUTHTOKEN_HERE\"; make test\n```\n\n_running an individual test_\n```shell\n# running an individual test\nexport NGROK_AUTHTOKEN=\"YOUR_AUTHTOKEN_HERE\"; make test=\"-k TEST_CLASS.NAME_OF_TEST\" test\n```\n\n[See the MakeFile for more examples](./Makefile)\n\n### HTTP2 \n\nThe examples include a minimal `hypercorn` HTTP/2 example if you run `make http2`. You can curl the endpoint logged with `INFO:ngrok.listener:Created` and verify the HTTP/2 response from `hypercorn`.\n\n```bash\ncurl --http2 -v https://\u003cYOUR_LISTENER_URL\u003e\n*   Trying \u003cYOUR_IP\u003e:443...\n* Connected to a6278d6c07ce.ngrok.app (\u003cYOUR_IP\u003e) port 443 (#0)\n* ALPN, offering h2\n* ALPN, offering http/1.1\n...\n\u003e GET / HTTP/2\n\u003e Host: a6278d6c07ce.ngrok.app\n\u003e user-agent: curl/7.81.0\n\u003e accept: */*\n\u003e\n...\n\u003c HTTP/2 200\n\u003c content-type: text/plain\n\u003c date: Fri, 01 Mar 2024 18:50:23 GMT\n\u003c ngrok-agent-ips: \u003cYOUR_AGENT_IP\u003e\n\u003c ngrok-trace-id: ed038ace04876818149cf0769bd43e38\n\u003c server: hypercorn-h2\n\u003c\n* TLSv1.2 (IN), TLS header, Supplemental data (23):\n* TLSv1.2 (IN), TLS header, Supplemental data (23):\n* Connection #0 to host \u003cYOUR_LISTENER_URL\u003e left intact\nhello\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngrok%2Fngrok-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fngrok%2Fngrok-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngrok%2Fngrok-python/lists"}