Skip to content

Python

The Python SDK is a convenient way to access Fathom's global flood risk intelligence data.

Note

The Fathom Python SDK only supports Python 3.9+

If you have an existing Python environment set up, you can add fathom-global-client-sdk to your existing requirements.txt file and install as normal.

Warning

With the release of the new V2 API, the Python SDK code has been moved into a different folder structure. To use the new V2 API, change your imports from

from fathom import Client
from proto.fathom import fathom_pb2, fathom_pb2_grpc

to

from fathom.sdk.v2 import Client
from fathom.api.v2 import fathom_pb2, fathom_pb2_grpc

To keep using the V1 API, only the client import should be changed to

from fathom.sdk.v1 import Client
# protobuf imports stay the same

Old imports will keep working for the time being, but will be removed in a future release.

Manual Installation

To use the Fathom Python module into a new virtualenv, proceed with the following steps.

# ensure you have the right requirements
python3 -m ensurepip

# Go to your project directory
cd /path/to/working/dir/
# Create a virtualenv in the 'venv' folder and activate it
python3 -m venv venv
source venv/bin/activate

# Install the package from pypi into the virtualenv
pip3 install fathom-global-client-sdk
Example
"""An example usage of the Fathom API client."""

import os

from fathom.sdk.v2 import Client, point, polygon, write_tiffs

if __name__ == "__main__":
    client = Client(
        os.getenv("FATHOM_CLIENT_ID"),
        os.getenv("FATHOM_CLIENT_SECRET"),
        os.getenv("FATHOM_API_ADDR"),
    )

    layer_ids = [
        "GLOBAL-1ARCSEC-00_OFFSET-1in10-PLUVIAL-DEFENDED-DEPTH-2020-PERCENTILE50-v0.0.0_test",
        "GLOBAL-1ARCSEC-00_OFFSET-1in100-PLUVIAL-DEFENDED-DEPTH-2020-PERCENTILE50-v0.0.0_test",
    ]

    # Get from points
    pt = point(lat=51.996147, lng=-2.159495)
    points_response = client.geo.get_points(([pt]), layer_ids)

    # Or using a polygon
    poly = polygon(
        [
            point(51.45, 0),
            point(51.55, 0),
            point(51.55, -0.1),
            point(51.45, -0.1),
            point(51.45, 0),
        ]
    )
    polygon_response = client.geo.get_polygon(poly, layer_ids)
    write_tiffs(
        polygon_response,
        output_dir,
    )

To use the 'asynchronous' large portfolio API as described in the portfolio documentation, you should use the portfolio client member like below snippet:

client = Client(...)
create_task_response = client.portfolio.create_task(...)

See the documentation for PortfolioClient for an in depth example of how to use it.

Loading from vector files

The Fathom Python SDK also supports loading polygons from:

  • KML files
  • KMZ archives
  • ESRI shapefiles
  • GeoPackage files
from fathom.sdk.v2 import Client

client = Client(...)
polygon_stats = client.vector_file_name.get_polygon_stats(
    "/path/to/file.kmz", layer_ids=[...]
)

In any of these files, the same restrictions as described in the basic usage documentation apply. Each file must contain exactly 1 polygon geometry and no other geometries.

Reference

Exceptions

SDK-specific exceptions are defined in the fathom.sdk.exceptions package.

V2 API

Client(client_id, client_secret, api_address='api.fathom.global', msg_channel_size=FATHOM_GRPC_CHANNEL_MSG_SIZE, *, grpc_interceptors=None)

Constructs a new Client, connected to a remote server.

Parameters:

Name Type Description Default
client_id str

Client ID to identify a registered client on the authorization server.

required
client_secret str

Client Secret used with client_id to get an access token.

required
api_address str

Address of the Fathom API server.

'api.fathom.global'
msg_channel_size int

gRPC message channel size, it is 10MB by default but if you will be dealing with data size larger than the default, you can configure the size.

FATHOM_GRPC_CHANNEL_MSG_SIZE

Attributes:

Name Type Description
geo GeoClient

Client to talk to the geospatial data API

geojson GeoJSONClient

Client to talk to the geospatial data API using GeoJSON

vector_file_name VectorFileClient

Client to talk to the geospatial data API using vector file formats

portfolio PortfolioClient

Client to talk to the large portfolio API

GeoClient(base_client) dataclass

A sub-client for synchronously fetching data for points or polygons.

get_points(points, layer_ids, project_id=None)

Returns data pertaining to a list of lat-lng coordinates.

Parameters:

Name Type Description Default
points List[Point]

A list of coordinates.

required
layer_ids List[str]

The identifiers of the types of data being requested.

required
project_id Optional[str]

Identifier to differentiate projects using the API.

None
get_polygon(polygon, layer_ids, project_id=None)

Returns data pertaining to a polygon coordinates.

Parameters:

Name Type Description Default
polygon Polygon

The bounding points of an area for which data are requested. The first and last point MUST be the same, and the loop MUST be in a counterclockwise direction (i.e. on the left-hand side of an observer walking along the boundary).

required
layer_ids List[str]

The identifiers of the types of data being requested.

required
project_id Optional[str]

Idenitifier to differentiate projects using the API.

None
get_polygon_stats(polygon, layer_ids, project_id=None)

Returns statistics about polygons using the given layer_ids

This is similar to the get_polygons method, but will only return statistics about the polygon, not the polygon itself. To see what statistics are returned, see the gRPC documentation

Parameters:

Name Type Description Default
polygon Polygon

The bounding points of an area for which data are requested. The first and last point MUST be the same, and the loop MUST be in a counterclockwise direction (i.e. on the left-hand side of an observer walking along the boundary).

required
layer_ids List[str]

The identifiers of the types of data being requested.

required
project_id Optional[str]

Idenitifier to differentiate projects using the API.

None

GeoJSONClient(base_client) dataclass

A client to fetch data from the fathom SDK using GeoJSON.

The geojson input to the method parameters should be one of:

  • An opened file object
  • A string or bytes containing raw GeoJSON
  • A PathLike object with the filepath to a geojson file
  • A Python dictionary containing the GeoJSON
GeoJSON queries
from fathom.sdk.v2 import Client

client = Client(...)
layer_ids = [...]

# With an opened file
with open("/path/to/geo.json") as geojson_file:
    polygon_resp = client.geojson.get_polygon_stats(geojson_file, layer_ids)

# With a geojson string
geojson_string = '{"type": ...}'
polygon_resp = client.geojson.get_polygon(geojson_string, layer_ids)

# With a Python dictionary
polygon_geojson = {
    ...
}
polygon_resp = client.geojson.get_polygon(polygon_geojson, layer_ids)
get_points(geojson, layer_ids, project_id=None)

Returns data pertaining to points encoded in GeoJSON.

get_polygon(geojson, layer_ids, project_id=None)

Returns data pertaining to a polygon coordinates encoded in GeoJSON.

get_polygon_stats(geojson, layer_ids, project_id=None)

Returns statistics about polygons using the given layer_ids

PortfolioClient(base_client) dataclass

Sub-client for interacting with portfolios

Triggering large portfolio requests
import time

from fathom.api.v2 import portfolio_pb2
from fathom.sdk.v2 import Client

client = Client(...)
layer_ids = [...]

create_resp = client.portfolio.create_task(layer_ids)

client.portfolio.upload_portfolio_csv(create_resp.upload_url, "/path/to/input.csv")

for i in range(100):
    time.sleep(10)

    status = client.portfolio.task_status(create_resp.task_id)
    if status.task_status == portfolio_pb2.TASK_STATUS_COMPLETE:
        break
    elif status.task_status == portfolio_pb2.TASK_STATUS_ERROR:
        raise Exception(f"task failed: {status}")
else:
    raise Exception("task was not ready in time")

num_bytes_read = client.portfolio.attempt_task_result_download(
    create_resp.task_id, "/path/to/output.csv"
)
attempt_task_result_download(task_id, output_path, chunk_size=1000)

Attempts to download the result of a given task. Should only be called after a call to task_status has indicated that the task completed without errors, otherwise an exception will be raised.

Parameters:

Name Type Description Default
task_id str

ID of previously created portfolio task

required
output_path PathOrString

Name of file to download output in to. It will be OVERWRITTEN if it already exists.

required
chunk_size int

Override chunk size when downloading CSV

1000

Returns:

Type Description
int

Number of bytes downloaded

Raises:

Type Description
TaskNotCompleteException

Task was not ready or there were errors during processing

create_task(layer_ids, project_id=None)

Create a new portfolio task

Parameters:

Name Type Description Default
layer_ids List[str]

Layer IDs to use for task

required
project_id Optional[str]

Identifier to differentiate projects using the API.

None
task_status(task_id)

Gets the status of an existing portfolio task

Parameters:

Name Type Description Default
task_id str

ID of previously created portfolio task

required
upload_portfolio_csv(upload_url, input_path, *, timeout=10) staticmethod

Uploads the given portfolio CSV file for the portfolio task

Parameters:

Name Type Description Default
upload_url str

upload url from a previous CreatePortfolioTaskResponse

required
input_path PathOrString

path to CSV file to upload

required
timeout int

timeout on uploading CSV

10

VectorFileClient(client) dataclass

Sub-client for fetching data using polygons encoded in vector files.

Supported vector types:

  • KML and KMZ files
  • GeoJSON
  • Shapefiles
  • GeoPackage

Each file must contain exactly one polygon 'feature' which follows the rules for other polygon queries.

Additionally, GeoJSON files must follow the same rules as defined in the GeoJSON query documentation.

Vector file queries
from fathom.sdk.v2 import Client

client = Client(...)
layer_ids = [...]

polygon_resp = client.vector_file_name.get_polygon_stats("/path/to/file.kml", layer_ids)
# On Windows, use the 'r' prefix to the path:
# polygon_resp = client.vector_file_name.get_polygon_stats(r"C:\Users\MyUser\file.kml", layer_ids)
get_polygon(vector_file_name, layer_ids, project_id=None, *, correct_polygon_points_order=False)

Returns data pertaining to a polygon contained in the given vector file.

Parameters:

Name Type Description Default
vector_file_name Union[str, PathLike]

path to a vector file in one of the supported formats

required
layer_ids List[str]

Layer IDs to use for task

required
project_id Optional[str]

Identifier to differentiate projects using the API.

None
correct_polygon_points_order bool

If set to True, attempt to correct the order of polygon points. If the polygon contained in the given vector file has points in the incorrect order (counter-clockwise) this will be rejected by the API, Enabling this option reverses the points before sending it to the API.

False
get_polygon_stats(vector_file_name, layer_ids, project_id=None, *, correct_polygon_points_order=False)

Returns stats pertaining to a polygon contained in the given vector file.

Parameters:

Name Type Description Default
vector_file_name Union[str, PathLike]

path to a vector file in one of the supported formats

required
layer_ids List[str]

Layer IDs to use for task

required
project_id Optional[str]

Identifier to differentiate projects using the API.

None
correct_polygon_points_order bool

If set to True, attempt to correct the order of polygon points. If the polygon contained in the given vector file has points in the incorrect order (counter-clockwise) this will be rejected by the API, Enabling this option reverses the points before sending it to the API.

False

point(lat, lng)

Returns a Point object for use with Client.get_point().

polygon(points)

Returns a Polygon object for use with Client.get_polygon().

write_tiffs(response, output_dir, *, pattern='{layer_id}.tif')

Given a polygon data response, write polygon tiff data in the response to the output directory.

If any polygon result in the response was fully 'no data' (see key values documentation), the output tiff will not be written.

Parameters:

Name Type Description Default
response GetPolygonDataResponse

A response from a get_polygon request

required
output_dir PathOrString

the directory to write the tiff data to

required
pattern str

The pattern to save the file as. Formatted using normal Python string formatting, with the only available key being : - 'layer_id': the layer id - 'sep': The os-specific directory separator

'{layer_id}.tif'