Get origin URL in FastAPI

Viewed 1979

Is it possible to get the URL that a request came from in FastAPI?

For example, if I have an endpoint that is requested at api.mysite.com/endpoint and a request is made to this endpoint from www.othersite.com, is there a way that I can retrieve the string "www.othersite.com" in my endpoint function?

2 Answers

The premise of the question, which could be formulated as

a server can identify the URL from where a request came

is misguided. True, some HTTP requests (especially some of the requests issued by browsers) carry an Origin header and/or a Referer [sic] header. Also, the Forwarded header, if present, contains information about where the request was issued. However, nothing in the HTTP specification requires that requests in general advertise where they came from.

Therefore, whether with FastAPI or some other server technology, there's no definite way of knowing where a request came from.

As per FastAPI documentation, and hence Starlette's:

Let's imagine you want to get the client's IP address/host inside of your path operation function.

@app.get("/items/{item_id}")
def read_root(item_id: str, request: Request):
    client_host = request.client.host
    return {"client_host": client_host, "item_id": item_id}

Please note, as pointed out by others, if you use nginx, you need to add headers to the nginx request to handle that data.

Update

Once you obtain the client's IP address (assuming that requests to your API are handled in the back-end of the website, and hence, the client's IP address would be the website's IP address and not the user's browsing the website), you can perform a reverse DNS lookup to get the website's server hostname (does not always exist though, or does not have a meaningful name), as shown below. From there, you can look up for information of the hostname, or the IP address itself, online. You can create a database with every IP address (or better hostname) you resolve for future reference.

import socket
#address = '2001:4860:4860::8888' # Google's Public DNS IPv6 address
address = '216.58.214.14' # a Google's IP address
print(socket.gethostbyaddr(address)[0])
Related