Skip to content

Instantly share code, notes, and snippets.

@liquidgenius
Last active September 19, 2022 04:23
Show Gist options
  • Save liquidgenius/7d249a24227e4f286b78fff52ec0177d to your computer and use it in GitHub Desktop.
Save liquidgenius/7d249a24227e4f286b78fff52ec0177d to your computer and use it in GitHub Desktop.
Syntactic sugar to seamlessly integrate Pyngrok with FastApi and Uvicorn. Useful in development where remote users may need to interact with local code.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__license__ = "MIT"
__version__ = "0.0.1"
__maintainer__ = "https://github.com/liquidgenius"
__status__ = "Development"
from pathlib import Path
from pyngrok import ngrok
from pyngrok.ngrok import NgrokTunnel
"""
USAGE
1. Install dependencies including FastAPI, Uvicorn and Pyngrok. (Poetry recommended.)
2. Save this code in app/core as PublicDevAccess.py.
3. Add a custom NGROK YAML config file to resources/ as ngrok.yml (just copy over yours from ~/.ngrok2)
4. Add the following code to your FastApi app:
from app.core import PublicDevAccess as PDA
#>>> your fastapi api code here <<<
if __name__ == "__main__":
print(f"Access: {PDA.public_url}/docs")
uvicorn.run(app, host='0.0.0.0', port=PDA.port, log_level="debug")
"""
def connect(config_path: Path, ensure_https: bool = True):
""" Connects to the NGROK service and returns a public url.
:param config_path: Path: The location of the custom NGROK config file. It is in YAML format.
:param ensure_https: bool: Flagged True as default to ensure only the https address is returned.
:return: str: The public URL your API may be accessed at.
"""
public_url = ngrok.connect(port=5050, config_path=config_path)
if ensure_https:
public_url = public_url.replace('http', 'https')
return public_url
def set_domain(public_url: str):
""" Extracts the domain from the public URL.
:param public_url:
:return: str: The domain of your API.
"""
domain = public_url.split('//')[-1]
return domain
def set_port(tunnel: NgrokTunnel):
""" Extracts the port from an NGROK tunnel.
:param tunnel: ngrok.NgrokTunnel: An Ngrok tunnel.
:return: int: The port number of the tunnel.
"""
port = int(tunnel.config['addr'].split(':')[-1])
return port
config_path = Path.cwd() / 'app' / 'resources' / 'ngrok.yml'
public_url = connect(config_path)
domain = set_domain(public_url)
process = ngrok.get_ngrok_process()
tunnels = ngrok.get_tunnels()
port = set_port(tunnels[0])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment