Todd Curry
Todd Curry

Reputation: 1083

How to parse subdomains from URLs in FastAPI?

Our customers are going to hit our new API at foo123.bar456.domain.com/v1.5/

The foo123 and bar456 subdomains are account-specific (and let us load balance). They signify relationships and trigger processing we need to do.

We don't want to (repetitively) pass query parameters in the URL, e.g., ...domain.com/v1.5/?acc=foo123&parent=bar456, as that is just non-pythonic, frankly.

So, I'd like to parse, in FastAPI, the fully-qualified domain name that was called.

I can't find tips on how to do this (URL parsing) that doesn't involve folders to the right of the fqdn. Tips / pointers? Thanks!

Upvotes: 1

Views: 707

Answers (1)

Chris
Chris

Reputation: 34095

You could call urllib.parse.urlparse() on request.url to get the hostname/domain name, and then further break it down into subdomains—inspired by this answer, as well as this answer and this answer.

Example

Using the example below, when typing, for instance, http://abc.def.localhost:8000/ in the address bar of the browser and hitting enter, it would return abc.def.localhost.

from fastapi import FastAPI, Request
import urllib


app = FastAPI()


@app.get('/')
def index(request: Request):
    url = urllib.parse.urlparse(str(request.url))
    return url.hostname

You could also further split the hostname, using dot (.) as the delimiter, in order to get the subdomains. Using the URL provided earlier, the example below would return ["abc","def"]. Example:

@app.get('/')
def index(request: Request):
    url = urllib.parse.urlparse(str(request.url))
    subs = url.hostname.split('.')
    return subs[:-1]

Update

One does not really have to use urllib.parse.urlparse(), in order to get the hostname. They could instead use request.url.hostname. Hence, the updated example would look like this:

from fastapi import FastAPI, Request


app = FastAPI()


@app.get('/')
def index(request: Request):
    subs = request.url.hostname.split('.')
    return subs[:-1]

Note that if the hostname, instead of abc.def.localhost, was, for instance, abc.def.example.com, you would then have to use subs[:-2] in the example above, in order to exclude the top and second level domains (i.e., com and example) from the list of subdomains.

Upvotes: 1

Related Questions