Search code examples
pythonpostdependency-injectionfastapidepends

FastAPI: can I use Depends() for parameters in a POST, too?


Overview

I have created a class-based dependency, similar to what is in the amazing FastAPI tutorial.

Problem

It works, except that the parameters in the dependency (the Depends() portion) are passed as query parameters, meaning that they are part of the URI/URL. I am using the class-based dependency as a means to simplify access to an Azure Datalake, so that the parameters in the Depends are at least somewhat secret. So I would prefer for them to be in the POST portion.

Question

Is there a way to use Depends(), but pass the class initialization parameters via the POST payload instead of in the URL path?

Details

As an example:

The dependency class (just the initialization, which captures the dependency parameters):

class DatalakeConnection(object):
    """Using FastAPI's `Depends` Dependency Injection, this class can have all
    elements needed to connect to a data lake."""

    def __init__(
        self,
        dir: str = my_typical_folder,
        container: str = storage_container.value,
    ):
        service_client = DataLakeServiceClient(
            account_url=storage_uri,
            credential=storage_credential,
        )
        self.file_system_client = service_client.get_file_system_client(
            file_system=container
        )
        self.directory_client = self.file_system_client.get_directory_client(dir)
        self.file_client = None

The FastAPI path function:

@app.post("/datalake")  # I have no response model yet, but will add one
def predictions_from_datalake(
    query: schemas.Query, conn: DatalakeConnection = Depends()
):
    core_df = conn.read_excel(query.file_of_interest) # I create a DataFrame from reading Excel files

Summary

As I said, this works, but the dir and container needed to initialize the class are forced into URL query parameters, but I would like for them to be key-value pairs in the request body of the POST:

Image of the Swagger UI showing the dir as a query parameter instead of part of the POST body


Solution

  • You can declare them just like path operation body parameters. More info here Singular values in body:

    class DatalakeConnection(object):
        """Using FastAPI's `Depends` Dependency Injection, this class can have all
        elements needed to connect to a data lake."""
    
        def __init__(
                self,
                dir: str = Body("dir_default"),
                container: str = Body("container_default"),
        ):
            pass
    

    Example of request body:

    {
      "dir": "string",
      "container": "string"
    }