question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[BUG] RedirectResponse returns 404 for external url's with TestClient

See original GitHub issue

Describe the bug

When trying to test a RedirectResponse with TestClient, it returns a 404 on any external url.

It seems related to this issue but there is an important difference: While in pure starlette, redirects work for urls in the form https://domain.tld/ and fail for https://domain.tld or any path or query parameters, with FastAPI, they fail for ANY external domain (see below).

Feel free to close this issue if it has nothing to do with FastAPI. I assume it has something to do with FastAPI as the behavior is different for FastAPI and pure starlette.

To Reproduce

  1. Create a file with:
from fastapi import FastAPI
from starlette.responses import RedirectResponse
from starlette.testclient import TestClient


def test_redirect():
    app = FastAPI()

    @app.get('/home')
    def home():
        return {}

    @app.get('/redirect_home')
    def redirect():
        return RedirectResponse(url='/home')

    @app.get('/redirect')
    def redirect():
        return RedirectResponse(url='https://www.github.com/')

    with TestClient(app) as client:
        response = client.get('/redirect_home')
        assert response.status_code == 200

        response = client.get('/redirect', allow_redirects=False)
        assert response.status_code == 307

        response = client.get('/redirect')
        assert response.status_code == 200
  1. Run the test with pytest.

The error I get:

            response = client.get('/redirect')
>           assert response.status_code == 200
E           assert 404 == 200

test_bug.py:29: AssertionError

Expected behavior

TestClient returns the correct status code for external urls.

Screenshots

If applicable, add screenshots to help explain your problem.

Environment

  • OS: macOS
  • FastAPI Version: 0.45.0
  • Python version:

Additional context

Add any other context about the problem here.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:6
  • Comments:7 (2 by maintainers)

github_iconTop GitHub Comments

20reactions
brumarcommented, Apr 2, 2020

I too scratched my head on this problem of 404’s for my attempts of redirection. I believe

response = client.get('/redirect', allow_redirects=False)
assert response.status_code == 307

Is indeed the way to go.

It seems that an assert based on the returned headers can be added

assert answer.headers["location"] == "your-external-url"
6reactions
tomchristiecommented, Dec 16, 2019

I’m not really sure what behaviour we’d want from the test client for external URLs. Or even how the test client could determine if it is an external URL?

Eg. If the service returns a redirect response to “https://api.myservice.com/users” how would we determine if that’s an external URL, or the service itself?

We also don’t really want the test client to make live network queries.

I can kind of see some approachs onto tightening up the behavior here, but it’s a complex area.

In the meantime I guess I’d suggest that you use allow_redirects=False for any test client calls that’ll result in an external host redirect.

Read more comments on GitHub >

github_iconTop Results From Across the Web

FastAPI RedirectResponse gets {"message" - Stack Overflow
It is basically just a header in itself and only allows for a URL. ... The cookie can be found in request.cookies —which...
Read more >
API — Flask Documentation (2.2.x)
For parts where Flask depends on external libraries, we document the most ... Matches the URL and returns the return value of the...
Read more >
FastAPI - The Blue Book
Validate the data: If the data is invalid, it will return a nice and clear error, indicating exactly where and what was the...
Read more >
Miguel Grinberg - Microdot
return {'error': 'resource not found'}, 404. The errorhandler() decorator has a second form, in which it takes an exception class as an ...
Read more >
Component Reference - Apache JMeter - User's Manual
If the request uses a technique called "URL Rewriting" to maintain ... If it is incorrect, the sampler will return an error and...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found