alexdlaird / pyngrok

A Python wrapper for ngrok
https://pyngrok.readthedocs.io
MIT License
416 stars 59 forks source link

django example attempts to open more than one ngrok instance when using runserver #122

Closed ITJamie closed 7 months ago

ITJamie commented 7 months ago

Describe the Bug when attempting to use the django example from the docs on a free ngrok account (one active tunnel limited) the django app will fail to run and complain about there already being an ngrok tunnel in use

Steps to Reproduce create an empty django project with the example added from docs use an authtoken on a basic free ngrok account run python3 manage.py runserver

Expected Behavior ngrok tunnel to start, django runserver to start correctly

Environment

Additional Context

python3 manage.py runserver
t=2023-11-29T16:31:47+0000 lvl=warn msg="ngrok config file found at legacy location, move to XDG location" xdg_path="/Users/jamie.murphy/Library/Application Support/ngrok/ngrok.yml" legacy_path=/Users/jamie.murphy/.ngrok2/ngrok.yml
ngrok tunnel "https://<ngrolurl>.ngrok.app" -> "http://127.0.0.1:8000"
t=2023-11-29T16:31:47+0000 lvl=warn msg="ngrok config file found at legacy location, move to XDG location" xdg_path="/Users/jamie.murphy/Library/Application Support/ngrok/ngrok.yml" legacy_path=/Users/jamie.murphy/.ngrok2/ngrok.yml
t=2023-11-29T16:31:47+0000 lvl=warn msg="can't bind default web address, trying alternatives" obj=web addr=127.0.0.1:4040

ERROR:  authentication failed: Your account is limited to 1 simultaneous ngrok agent session.
ERROR:  You can run multiple tunnels on a single agent session using a configuration file.
ERROR:  To learn more, see https://ngrok.com/docs/secure-tunnels/ngrok-agent/reference/config/
ERROR:  
ERROR:  Active ngrok agent sessions in region 'eu':
ERROR:    - <sessionid> (<ip>)
ERROR:  
ERROR:  ERR_NGROK_108
ERROR:  
t=2023-11-29T16:31:47+0000 lvl=eror msg="failed to reconnect session" obj=tunnels.session obj=csess id=ffbf7f69af2c err="authentication failed: Your account is limited to 1 simultaneous ngrok agent session.\nYou can run multiple tunnels on a single agent session using a configuration file.\nTo learn more, see https://ngrok.com/docs/secure-tunnels/ngrok-agent/reference/config/\n\nActive ngrok agent sessions in region 'eu':\n  - <sessionid> (<ip>)\r\n\r\nERR_NGROK_108\r\n"
t=2023-11-29T16:31:47+0000 lvl=eror msg="session closing" obj=tunnels.session err="authentication failed: Your account is limited to 1 simultaneous ngrok agent session.\nYou can run multiple tunnels on a single agent session using a configuration file.\nTo learn more, see https://ngrok.com/docs/secure-tunnels/ngrok-agent/reference/config/\n\nActive ngrok agent sessions in region 'eu':\n  - <sessionid> (<ip>)\r\n\r\nERR_NGROK_108\r\n"
t=2023-11-29T16:31:47+0000 lvl=eror msg="terminating with error" obj=app err="authentication failed: Your account is limited to 1 simultaneous ngrok agent session.\nYou can run multiple tunnels on a single agent session using a configuration file.\nTo learn more, see https://ngrok.com/docs/secure-tunnels/ngrok-agent/reference/config/\n\nActive ngrok agent sessions in region 'eu':\n  - <sessionid> (<ip>)\r\n\r\nERR_NGROK_108\r\n"
t=2023-11-29T16:31:47+0000 lvl=warn msg="failed to check for update" obj=updater err="Post \"https://update.equinox.io/check\": context canceled"
Watching for file changes with StatReloader
Exception in thread django-main-thread:
Traceback (most recent call last):
  File "/Users/jamie.murphy/.pyenv/versions/3.9.7/lib/python3.9/threading.py", line 973, in _bootstrap_inner
    self.run()
  File "/Users/jamie.murphy/.pyenv/versions/3.9.7/lib/python3.9/threading.py", line 910, in run
    self._target(*self._args, **self._kwargs)
  File "/apppath/venv/lib/python3.9/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/apppath/venv/lib/python3.9/site-packages/django/core/management/commands/runserver.py", line 125, in inner_run
    autoreload.raise_last_exception()
  File "/apppath/venv/lib/python3.9/site-packages/django/utils/autoreload.py", line 87, in raise_last_exception
    raise _exception[1]
  File "/apppath/venv/lib/python3.9/site-packages/django/core/management/__init__.py", line 394, in execute
    autoreload.check_errors(django.setup)()
  File "/apppath/venv/lib/python3.9/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/apppath/venv/lib/python3.9/site-packages/django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/apppath/venv/lib/python3.9/site-packages/django/apps/registry.py", line 124, in populate
    app_config.ready()
  File "/apppath/pxwhmcsbridge/hooker/apps.py", line 23, in ready
    public_url = ngrok.connect(port).public_url
  File "/apppath/venv/lib/python3.9/site-packages/pyngrok/ngrok.py", line 309, in connect
    api_url = get_ngrok_process(pyngrok_config).api_url
  File "/apppath/venv/lib/python3.9/site-packages/pyngrok/ngrok.py", line 153, in get_ngrok_process
    return process.get_process(pyngrok_config)
  File "/apppath/venv/lib/python3.9/site-packages/pyngrok/process.py", line 234, in get_process
    return _start_process(pyngrok_config)
  File "/apppath/venv/lib/python3.9/site-packages/pyngrok/process.py", line 395, in _start_process
    raise PyngrokNgrokError("The ngrok process errored on start: {}.".format(ngrok_process.startup_error),
pyngrok.exception.PyngrokNgrokError: The ngrok process errored on start: authentication failed: Your account is limited to 1 simultaneous ngrok agent session.\nYou can run multiple tunnels on a single agent session using a configuration file.\nTo learn more, see https://ngrok.com/docs/secure-tunnels/ngrok-agent/reference/config/\n\nActive ngrok agent sessions in region 'eu':\n  - <sessionid> (<ip>)\r\n\r\nERR_NGROK_108\r\n.
t=2023-11-29T16:32:15+0000 lvl=warn msg="failed to open private leg" id=6e03c374b165 privaddr=localhost:8000 err="dial tcp 127.0.0.1:8000: connect: connection refused"
t=2023-11-29T16:32:16+0000 lvl=warn msg="failed to open private leg" id=ce1f4b21d20d privaddr=localhost:8000 err="dial tcp 127.0.0.1:8000: connect: connection refused"
^C%                       

i believe this to be related to what was mentioned in: https://github.com/alexdlaird/pyngrok/issues/52

django's manage.py runserver starts two threads. the master file watcher thread and the actual app-running thread. the example code should be adjusted to only run in one of these

alexdlaird commented 7 months ago

Can you provide an example where you also show the env vars you have set (which should match the documentation example as well)?

The RUN_MAIN env var is what Django uses to determine which thread you're in when the autoreloader is using. It's possible the latest version of Django somehow changes this functionality and we need to distinguish which thread we're in in some other way now? But I'd need to see more about your code / env in comparison to the docs to troubleshoot before I dig in to this further.

alexdlaird commented 7 months ago

Just used django-admin in 4.x to init a new Django project, followed the integration example in the pyngrok docs, all still works fine. pyngrok is only initialized in the main thread on the dev server, so only one tunnel is opened, which means it will work with a free account. Closing this until more information is provided for how to reproduce the error.