Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ROOT PATH is broken for all use cases #1262

Closed
stephenrs opened this issue Aug 26, 2024 · 14 comments
Closed

ROOT PATH is broken for all use cases #1262

stephenrs opened this issue Aug 26, 2024 · 14 comments
Labels
bug Something isn't working

Comments

@stephenrs
Copy link

stephenrs commented Aug 26, 2024

Describe the bug
The hello.py script works fine for me with the latest build, but my test app never connects to the server. The test app works fine with v1.1.402.

Nothing appears in the debug log that indicates a problem, as follows:

INFO:     1.1.1.1:0 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6CPni3 HTTP/1.1" 200 OK
INFO:     1.1.1.1:0 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6CPp9p HTTP/1.1" 200 OK
INFO:     1.1.1.1:0 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6CPqdZ HTTP/1.1" 200 OK
etc...

Note: 1.1.1.1 is not my actual LAN IP address

However, I'm using nginx as a reverse proxy, and the nginx error log shows this:

[error] 72918#0: *5798 kevent() reported that connect() failed (61: Connection refused) while connecting to upstream, client: 1.1.1.1, server: server.name, request: "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6CRLYY HTTP/1.1", upstream: "http://127.0.0.1:8000/chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6CRLYY", host: "server.name", referrer: "https://server.name/chainlit"

To Reproduce

  1. Follow the steps here: https://github.com/Chainlit/chainlit/blob/08489776ae2c84a75aa01d1069f47fc4f938f07e/.github/CONTRIBUTING.md
  2. Add a location block to the nginx configuration as follows:
location /chainlit {
        proxy_pass http://127.0.0.1:8000/chainlit;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Preserve cookies and session
        proxy_set_header Cookie $http_cookie;
        proxy_pass_request_headers on;

        # Preserve Authorization and custom headers
        proxy_set_header Authorization $http_authorization;
        proxy_set_header X-Custom-Header $http_x_custom_header;

        # Additional headers for WebSockets
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
  1. Create a minimal app.py
  2. Start the server with: poetry run chainlit run path/to/app.py --root-path /chainlit -d
  3. Go to your HTTP(S)://your.servername/chainlit
  4. View the "Could not reach..." error on the main UI

Expected behavior
The connection to the server should succeed and the input box should be enabled.

Desktop (please complete the following information):

  • OS: MacOS
  • Browser: Chrome
  • Version: 128.0.6613.85
@dokterbob
Copy link
Collaborator

Seems a deployment issue to me. Are you sure Chainlit is running on http://127.0.0.1:8000? Can you make requests there, e.g. with curl? Might it be something else is already listening on :8000, preventing chainlit from binding there?

Note that if Chainlit can't open a socket yet won't give an error message that would be a bug on our side and we'd like to know about it. :)

@stephenrs
Copy link
Author

@dokterbob I've confirmed that CL is running on http://127.0.0.1:8000 and doesn't have any port binding conflicts. More specifically, when CL is started without a root path (thereby bypassing the nginx location block), the UI opens in a browser normally and establishes a connection:

chainlit run path/to/app.py --port 8000 -d

However, when the root path is specified (thereby allowing nginx to reverse proxy requests), the UI opens in a browser and "Could not reach..." error occurs:

chainlit run path/to/app.py --port 8000 -d --root-path /chainlit

The identical tests work fine with 1.1.402.

However, today in re-testing I noticed errors in the debug log that seem informative:

INFO:     Started server process [13398]
INFO:     Waiting for application startup.
2024-08-26 11:56:56 - Your app is available at http://localhost:8000/chainlit
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:51797 - "GET /chainlit HTTP/1.1" 307 Temporary Redirect
INFO:     127.0.0.1:51797 - "GET /chainlit/ HTTP/1.1" 200 OK
INFO:     127.0.0.1:51797 - "GET /chainlit/auth/config HTTP/1.1" 200 OK
INFO:     127.0.0.1:51799 - "GET /chainlit/project/translations?language=en-US HTTP/1.1" 200 OK
2024-08-26 11:56:58 - Translated markdown file for en-US not found. Defaulting to chainlit.md.
INFO:     127.0.0.1:51799 - "GET /chainlit/project/settings?language=en-US HTTP/1.1" 200 OK
INFO:     127.0.0.1:51799 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6FrNpK HTTP/1.1" 200 OK
INFO:     127.0.0.1:51799 - "GET /ws/socket.io/?EIO=4&transport=polling&t=P6FrNsl HTTP/1.1" 404 Not Found
INFO:     127.0.0.1:51797 - "GET /ws/socket.io/?EIO=4&transport=polling&t=P6FrNsm HTTP/1.1" 404 Not Found
INFO:     127.0.0.1:51797 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6FrO4U HTTP/1.1" 200 OK
INFO:     127.0.0.1:51797 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6FrOL- HTTP/1.1" 200 OK
INFO:     1.1.1.1:0 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6FrObc HTTP/1.1" 200 OK
INFO:     127.0.0.1:51797 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6FrOcK HTTP/1.1" 200 OK
INFO:     127.0.0.1:51797 - "GET /ws/socket.io/?EIO=4&transport=polling&t=P6FrPKU HTTP/1.1" 404 Not Found
INFO:     127.0.0.1:51847 - "GET /ws/socket.io/?EIO=4&transport=polling&t=P6FrPKV HTTP/1.1" 404 Not Found
INFO:     127.0.0.1:51847 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6FrPee HTTP/1.1" 200 OK
INFO:     127.0.0.1:51847 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6FrPpk HTTP/1.1" 200 OK
INFO:     1.1.1.1:0 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6FrQ3M HTTP/1.1" 200 OK
INFO:     1.1.1.1:0 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6FrQ3u HTTP/1.1" 200 OK
INFO:     1.1.1.1:0 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6FrQ4I HTTP/1.1" 200 OK
INFO:     1.1.1.1:0 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6FrQ4g HTTP/1.1" 200 OK
INFO:     127.0.0.1:51847 - "GET /chainlit/project/translations?language=en-US HTTP/1.1" 200 OK
INFO:     127.0.0.1:51847 - "GET /ws/socket.io/?EIO=4&transport=polling&t=P6FrQoE HTTP/1.1" 404 Not Found
INFO:     127.0.0.1:51879 - "GET /ws/socket.io/?EIO=4&transport=polling&t=P6FrQoF HTTP/1.1" 404 Not Found

It looks like some requests don't include the root-path, and some use the localhost IP while some use my computer's LAN IP. Hope this helps, and if you see anything in my nginx config that could explain this, please let me know (but it seems pretty vanilla/basic).

In case it might be relevant, I'll also note that my local server uses SSL only, but I have not configured SSL explicitly in CL. I don't actually intend to, which is one reason for the reverse proxy setup.

@stephenrs
Copy link
Author

#1252 could be the same problem.

@dokterbob
Copy link
Collaborator

@stephenrs Thanks for the additional feedback.

If I get it well, with chainlit mounted on a subpath, under some conditions, the wrong URL is used sometimes by the frontend to connect to the websocket. Does that sound correct?

Could you perhaps supply a minimal test project (GIT repo or ZIP or whatever) so we can replicate/work on the issue?

I'm not sure whether #1252 is the same issue, hard to asses from the information provided. But I do think #1260 tries to address the same issue.

I would love to see #1223 implemented, to get rid of mount_chainlit() and to have generic URL resolution. At this point, I love any community feedback on the pro's/con's of my concept there -- so when it's implemented it should be a huge step forwards.

@stephenrs
Copy link
Author

stephenrs commented Aug 28, 2024

@dokterbob I've attached a zip file containing 3 files:

  1. test_connect.py - a minimal app target
  2. test_handler.py - an EventHandler dependency of test_connect.py
  3. test_nginx.conf - the relevant location block in my nginx config

I used the OAI Assistants cookbook example as my starting point, so you might recognize most of the code.

I also recently added the CORS stuff to the nginx config to make sure CORS wasn't the problem, but it didn't make a difference and 1.1.402 doesn't need it.

Seems like the recent changes to server.py might be to blame.

Here's the log output from the startup of both the default and nginx proxy approaches:

chainlit run path/to/test_connect.py --port 8000 -d - avoids nginx, connects fine

2024-08-28 15:15:36 - Loaded .env file
2024-08-28 15:15:37 - HTTP Request: GET https://api.openai.com/v1/assistants/asst_# "HTTP/1.1 200 OK"
INFO:     Started server process [17186]
INFO:     Waiting for application startup.
2024-08-28 15:15:37 - Your app is available at http://localhost:8000
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:54276 - "GET / HTTP/1.1" 200 OK
INFO:     127.0.0.1:54276 - "GET /auth/config HTTP/1.1" 200 OK
INFO:     127.0.0.1:54278 - "GET /project/translations?language=en-US HTTP/1.1" 200 OK
2024-08-28 15:15:39 - Translated markdown file for en-US not found. Defaulting to chainlit.md.
INFO:     127.0.0.1:54278 - "GET /project/settings?language=en-US HTTP/1.1" 200 OK
INFO:     127.0.0.1:54278 - "GET /ws/socket.io/?EIO=4&transport=polling&t=P6Qs1lz HTTP/1.1" 200 OK
INFO:     127.0.0.1:54278 - "POST /ws/socket.io/?EIO=4&transport=polling&t=P6Qs1mF&sid=fqSRZGGe735WplSoAAAA HTTP/1.1" 200 OK
INFO:     127.0.0.1:54276 - "GET /ws/socket.io/?EIO=4&transport=polling&t=P6Qs1mG&sid=fqSRZGGe735WplSoAAAA HTTP/1.1" 200 OK
INFO:     ('127.0.0.1', 54284) - "WebSocket /ws/socket.io/?EIO=4&transport=websocket&sid=fqSRZGGe735WplSoAAAA" 
INFO:     127.0.0.1:54276 - "GET /ws/socket.io/?EIO=4&transport=polling&t=P6Qs1mM&sid=fqSRZGGe735WplSoAAAA HTTP/1.1" 200 OK
INFO:     127.0.0.1:54278 - "POST /ws/socket.io/?EIO=4&transport=polling&t=P6Qs1mN&sid=fqSRZGGe735WplSoAAAA HTTP/1.1" 200 OK
INFO:     127.0.0.1:54278 - "GET /ws/socket.io/?EIO=4&transport=polling&t=P6Qs1ml&sid=fqSRZGGe735WplSoAAAA HTTP/1.1" 200 OK
2024-08-28 15:15:40 - HTTP Request: POST https://api.openai.com/v1/threads "HTTP/1.1 200 OK"
2024-08-28 15:15:47 - HTTP Request: POST https://api.openai.com/v1/threads/thread_#/messages "HTTP/1.1 200 OK"
2024-08-28 15:15:48 - HTTP Request: POST https://api.openai.com/v1/threads/thread_#/runs "HTTP/1.1 200 OK"
INFO:     127.0.0.1:54483 - "GET /project/translations?language=en-US HTTP/1.1" 200 OK
2024-08-28 15:16:25 - HTTP Request: POST https://api.openai.com/v1/threads/thread_#/messages "HTTP/1.1 200 OK"
2024-08-28 15:16:26 - HTTP Request: POST https://api.openai.com/v1/threads/thread_#/runs "HTTP/1.1 200 OK"

chainlit run path/to/test_connect.py --port 8000 -d --root-path /chainlit - nginx proxies requests, falls to connect

2024-08-28 15:17:56 - Loaded .env file
2024-08-28 15:17:57 - HTTP Request: GET https://api.openai.com/v1/assistants/asst_# "HTTP/1.1 200 OK"
INFO:     Started server process [18321]
INFO:     Waiting for application startup.
2024-08-28 15:17:57 - Your app is available at http://localhost:8000/chainlit
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:54953 - "GET /chainlit HTTP/1.1" 307 Temporary Redirect
INFO:     127.0.0.1:54953 - "GET /chainlit/ HTTP/1.1" 200 OK
INFO:     127.0.0.1:54953 - "GET /chainlit/auth/config HTTP/1.1" 200 OK
INFO:     127.0.0.1:54955 - "GET /chainlit/project/translations?language=en-US HTTP/1.1" 200 OK
2024-08-28 15:18:00 - Translated markdown file for en-US not found. Defaulting to chainlit.md.
INFO:     127.0.0.1:54955 - "GET /chainlit/project/settings?language=en-US HTTP/1.1" 200 OK
INFO:     127.0.0.1:54955 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6QsaEw HTTP/1.1" 200 OK
INFO:     127.0.0.1:54955 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6Qsaah HTTP/1.1" 200 OK
INFO:     127.0.0.1:54955 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6Qsas1 HTTP/1.1" 200 OK
INFO:     127.0.0.1:54955 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6QsbUn HTTP/1.1" 200 OK
INFO:     127.0.0.1:55011 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6Qsciy HTTP/1.1" 200 OK
INFO:     127.0.0.1:55033 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6Qsdx9 HTTP/1.1" 200 OK
INFO:     127.0.0.1:55055 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6Qsf9M HTTP/1.1" 200 OK
INFO:     127.0.0.1:55078 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6QsgNb HTTP/1.1" 200 OK
INFO:     127.0.0.1:55100 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6Qshbn HTTP/1.1" 200 OK
INFO:     127.0.0.1:55122 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6Qsip- HTTP/1.1" 200 OK
INFO:     127.0.0.1:55147 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6Qsk2A HTTP/1.1" 200 OK
INFO:     127.0.0.1:55169 - "GET /chainlit/ws/socket.io/?EIO=4&transport=polling&t=P6QslGO HTTP/1.1" 200 OK

Hope this helps. Let me know if you need anything else.

[accepted]
test-1.1.403rc0.zip

@dokterbob
Copy link
Collaborator

Thanks @stephenrs for providing the feedback and the test project.

However, I am unable to run it because it seems I need an assistant_id. I guess I'd need to setup an assistant etc.

I will not ask you to send me your OpenAI API key and setting up an assistant for an issue unrelated to assistants is really not in scope. Hope you understand, although I would really help to solve this issue, and I can definitely think that adding an example nginx config to docs regarding deployment is a Good Thing(tm).

I am also not aware what EventHandler has to do with the issue at hand.

Ideally, I would love a unit or e2e test, failing on the specific issue you're having.

Second to that, very specific instructions to replicate your issue (e.g. clear steps), including test project with minimal dependencies as some guidance how to recognise the issue. For example, while your initial logs showed 404's and incorrect pathnames, the logs you posted above only have 200's and correct pathnames.

Thanks for helping us move this forward!

@stephenrs
Copy link
Author

However, I am unable to run it because it seems I need an assistant_id. I guess I'd need to setup an assistant etc.

I guess I assumed you guys would have test accounts with the LLMs to use to facilitate investigating related problems (folks don't seem likely to publicize their OAI/Assistant credentials when problems arise). Also, since the logs don't give an indication of what is failing, causing the app to decide that it can't reach the server, or whether it has anything to do with connecting to an assistant, I thought a test app that is a little closer to a real-world scenario might be helpful.

I am also not aware what EventHandler has to do with the issue at hand.

As above, I wasn't sure either, but since it's CL's code I guess I didn't think it would be problematic :) The EventHandler handles streaming responses and I got it from the example project here: https://github.com/Chainlit/openai-assistant

In any case, however, I've discovered that you don't need a test app to reproduce the issue. You can observe it with the included hello.py target by specifying a root path when you run it.

There are steps to reproduce in the original report, but it's actually simpler, as below (from the project root):

cd backend
poetry run chainlit run chainlit/hello.py --root-path /bob

Instead of "What is your name?", when my browser opens to http://localhost:8000/bob it says "Could not reach the server." Running "poetry run chainlit run chainlit/hello.py" works as expected, as does specifying a root path in 1.1.402.

So, it doesn't appear to be related to the nginx proxy.

For example, while your #1262 (comment) showed 404's and incorrect pathnames, the logs you posted above only have 200's and correct pathnames.

I realized that the first time I posted the logs I had another tab(s) open that was also trying to contact the CL server. The most recent logs represent a "clean" test. Sorry for the confusion.

@dokterbob
Copy link
Collaborator

Quick comment (haven't yet had time to read your response above).

Could the (undocumented) CHAINLIT_URL be the solution to the problem you're facing?
https://github.com/search?q=repo%3AChainlit%2Fchainlit%20CHAINLIT_URL&type=code

@Tug
Copy link

Tug commented Sep 6, 2024

I'm having the same issue but using mount_chainlit on a fastapi app instead. The socket path used seems fine on the client but the response returned is the html page, thus the error.

@dokterbob
Copy link
Collaborator

In any case, however, I've discovered that you don't need a test app to reproduce the issue. You can observe it with the included hello.py target by specifying a root path when you run it.

Sweet, this is the information I need. We get lot's of feedback and PR's and due to the huge number of use cases and integrations supported (and thus far lack of test coverage), our challenge pertains to keeping track of and switching between use cases.

That's why having clear reproduction steps and/or a demo project really helps.
Now we have a bit more info, me or some other contrib can more easily address the issue.

@Tug I've found your description a bit hard to understand. Please, if you can, explain the issue your facing a bit more clearly. Thanks!

@dokterbob dokterbob added bug Something isn't working and removed needs-triage labels Sep 6, 2024
@dokterbob dokterbob changed the title "Could not reach the server." error with the 1.1.403rc0 build Unable to connect behind a proxy with --root Sep 6, 2024
@Tug
Copy link

Tug commented Sep 6, 2024

The error is the same but the test case is different, I'll open another issue 👍

Edit: opened #1317

@stephenrs
Copy link
Author

stephenrs commented Sep 6, 2024

@dokterbob I noticed that you changed the title of this issue, but as I've commented above this is not related to the proxy, because the proxy is not involved in the latest reproduction steps I noted. The root-path seems to be broken with or without a proxy, as @Tug is experiencing.

I initially provided a more complex test case involving a proxy because I guess I just assumed it wouldn't be possible that something so fundamental and globally affecting would be released without testing. I trusted "--root-path", but it appears to be broken for any case.

@stephenrs
Copy link
Author

Looks like this is the same thing: #1313

So it seems like anyone who uses root-path should freeze themselves on 1.1.402 until this project stabilizes.

@stephenrs stephenrs changed the title Unable to connect behind a proxy with --root CRITICAL: ROOT PATH is broken for all use cases Sep 8, 2024
@dokterbob dokterbob changed the title CRITICAL: ROOT PATH is broken for all use cases ROOT PATH is broken for all use cases Sep 10, 2024
@dokterbob
Copy link
Collaborator

Looks like this is the same thing: #1313

So it seems like anyone who uses root-path should freeze themselves on 1.1.402 until this project stabilizes.

I am assuming this is the same as #1313, so addressed by #1337, so closing this one.

If the issue persists, please provide as minimal as possible replication case as I have not been able to replicate the issue based on instructions here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants