2

I take the IP address using client.host from the Request object and send this to another function, where I'm using Pydantic's IPvAnyAddress to validate the IP address.

Here is my code:

from fastapi import APIRouter, Request
from pydantic import IPvAnyAddress


route = APIRouter()


@route.get("/ip-address")
def request_ip_address_deblock_link(request: Request):
    return example_function(request.client.host)

def example_function(ip_address: IPvAnyAddress):
    print(ip_address)

But when I'm using FastAPI's TestClient to test my API routes, the IP-address check fails, as the hostname in the request is testclient.

ValueError: 'testclient' does not appear to be an IPv4 or IPv6 address

Is it possible to change the hostname in FastAPI/Starlette's TestClient?

3
  • As far as I can tell the clients hostname is hardcoded as testclient in starlette.testclient.TestClient, but you might be able to go through having a custom portal_factory that changes the content of scope before using the original portal_factory? Also note that the TestClient changed from being based on requests to httpx in the last couple of days, so there might be a slight behavior change here (even if there shouldn't be one). Commented Sep 9, 2022 at 11:13
  • @MatsLindh From the source code (cited below), it doesn't seem that portal_factory is related to scope. Is it? Commented Sep 9, 2022 at 11:26
  • @Chris When the portal gets called, it receives scope as one of its parameters. But it seems to only happen after the request has happened: github.com/encode/starlette/blob/… - I'm not familiar with the portal, but it's user configurable and has access to scope at least somewhere in the request cycle, so that would be my best bet. Commented Sep 9, 2022 at 11:57

2 Answers 2

1

The scope["client"] was changed to None on master in Starlette.

After the next release, you should not have any issue.

Disclaimer: Starlette maintainer.

Sign up to request clarification or add additional context in comments.

1 Comment

I am running starlette 0.36.3 and is set to None. Do I understand correctly that should be corectly populated? What release fixes that? I don't see that in release notes up to 0.37.1
0

From Starlette's source code on testclient.py here—that FastAPI actually uses under the hood, see here)—the testclient hostname seems to be fixed/hardcoded.

Hence, you could simply check on server side if request.client.host == 'testclient' inside a Dependency function (as @MatsLindh suggested in the comments section), and next, either override testclient with the local IP address, or raise some exception (if you like).

Alternatively, you could use the HTTPX library, also suggested in the FastAPI documentation. FastAPI/Starlette's TestClient is now built on httpx (see the relevant commit on github).

1 Comment

Or you could move get_client_ip_address out to a dependency with Depends() and then override that in the testing context

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.