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.10+

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.

Custom exceptions for the Fathom SDK.

AuthenticationError

Bases: FathomException

Could not create an authenticated connection to the API.

FathomException

Bases: Exception

A client exception.

GeoJSONError

Bases: FathomException

Invalid GeoJSON given.

InvalidCredentialsError

Bases: FathomException

Could not create an authenticated connection to the API.

KMLError

Bases: FathomException

Invalid KML/KMZ given.

PortfolioCSVError

Bases: FathomException

Error when uploading data for a large portfolio run.

TaskNotCompleteException

Bases: FathomException

Tried to download the result from a task that was not complete.

VectorFileError

Bases: FathomException

Invalid vector file given.

Utility functions

Common utility functions for the Fathom SDK.

check_polygon_order(geojson, correct_polygon_points_order=False)

Check if the polygon contained in the geojson is in the right order.

This function can only check the polygon order if there is exactly one Polygon at the top level of the GeoJSON. Some errors (e.g. nested polygons, invalid GeoJSON structure) may not be caught by this function and will only be detected by the server. If correct_polygon_points_order is True and the points in the given polygon are in the wrong order (clockwise instead of counter-clockwise), this function reverses the points in the GeoJSON in-place. If correct_polygon_points_order is False, it logs a warning instead.

Parameters:

Name Type Description Default
geojson Dict

The loaded GeoJSON

required
correct_polygon_points_order bool

if True, and the points in the given polygon are in the wrong order (clockwise instead of counter-clockwise), reverse the points in the GeoJSON in place. If False, log a warning and continue.

False

Raises:

Type Description
GeoJSONError

If the GeoJSON is missing a geometry type.

Note

This function modifies the input GeoJSON in-place.

Example
import json
from fathom.sdk.common import check_polygon_order

poly = json.loads('{"type": "Polygon", "coordinates": [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]]]}')
check_polygon_order(poly)

write_tiff_data_to_file(geotiff_bytes, layer_id, output_dir, pattern, tiff_num)

Write GeoTIFF data to a file based on the provided pattern and parameters.

Parameters:

Name Type Description Default
geotiff_bytes bytes

The byte data of the GeoTIFF to be written.

required
layer_id str

The identifier for the layer.

required
output_dir PathOrString

The directory where the file will be saved.

required
pattern str

The filename pattern to use, which can include placeholders for sep, layer_id, and tiff_num.

required
tiff_num int

The number of the TIFF file, used in the filename pattern.

required

Raises:

Type Description
OSError

If there is an issue creating the directory or writing the file.

V2 API

Functions for interacting with the V2 Fathom API.

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

Fathom SDK v2 client.

Construct 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
grpc_interceptors Optional[List[UnaryUnaryClientInterceptor]]

An optional list of grpc interceptors to add to the grpc channel, for logging or other purposes.

None

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_large_polygon(polygon, layer_ids, project_id=None)

Return data pertaining to a large 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]

Identifier to differentiate projects using the API.

None

Returns:

Type Description
GetLargePolygonDataResponse

A GetLargePolygonDataResponse object containing the data for the large polygon.

Fetching large polygon data
import requests

from fathom.api.v2 import fathom_pb2
from fathom.sdk.v2 import Client, point, polygon

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

# Define a polygon
poly = polygon([
    point(51.50, -0.12),
    point(51.51, -0.12),
    point(51.51, -0.11),
    point(51.50, -0.11),
    point(51.50, -0.12),
])

# Request the large polygon data
large_poly_resp = client.geo.get_large_polygon(poly, layer_ids)

# Print the result codes for each layer
print("Result codes per layer:")
for layer_id, result_code in large_poly_resp.result_codes.items():
    # Map the integer result code to its string name
    result_code_name = fathom_pb2.PolygonResultCode.Name(result_code)
    print(f"  {layer_id}: {result_code_name}")

# Download the data using the provided URL
download_url = large_poly_resp.download_url
print(f"Downloading data from: {download_url}")

response = requests.get(download_url)
response.raise_for_status() # Raise an exception for bad status codes

# Process the downloaded data (e.g., save to a file)
with open("large_polygon_data.zip", "wb") as f:
    f.write(response.content)
get_points(points, layer_ids, project_id=None)

Return 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

Returns:

Type Description
GetPointsDataResponse

A GetPointsDataResponse object containing the data for the points.

get_polygon(polygon, layer_ids, project_id=None)

Return 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]

Identifier to differentiate projects using the API.

None

Returns:

Type Description
GetPolygonDataResponse

A GetPolygonDataResponse object containing the data for the polygon.

get_polygon_stats(polygon, layer_ids, project_id=None)

Return 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]

Identifier to differentiate projects using the API.

None

Returns:

Type Description
GetPolygonStatsResponse

A GetPolygonStatsResponse object containing the statistics for the polygon.

quote_points(points, layer_ids)

Quote the cost to get points data.

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

Returns:

Type Description
QuotePointsResponse

A QuotePointsResponse object containing the quote for the points data.

quote_polygon(polygon, layer_ids)

Quote the cost to get polygon data.

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

Returns:

Type Description
QuotePolygonResponse

A QuotePolygonResponse object containing the quote for the polygon data.

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_large_polygon(geojson, layer_ids, project_id=None)

Return data pertaining to a large polygon encoded in GeoJSON.

Parameters:

Name Type Description Default
geojson Union[PathLike, str, bytes, bytearray, BufferedIOBase, TextIOBase, Dict]

The GeoJSON data representing the polygon. - 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

required
layer_ids List[str]

Layer IDs to use for task

required
project_id Optional[str]

Identifier to differentiate projects using the API.

None

Returns:

Type Description
GetLargePolygonDataResponse

A GetLargePolygonDataResponse object containing the data for the large polygon.

get_points(geojson, layer_ids, project_id=None)

Return data pertaining to points encoded in GeoJSON.

Parameters:

Name Type Description Default
geojson Union[PathLike, str, bytes, bytearray, BufferedIOBase, TextIOBase, Dict]

The GeoJSON data representing the points. - 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

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

Returns:

Type Description
GetPointsDataResponse

A GetPointsDataResponse object containing the data for the points.

get_polygon(geojson, layer_ids, project_id=None)

Return data pertaining to a polygon encoded in GeoJSON.

Parameters:

Name Type Description Default
geojson Union[PathLike, str, bytes, bytearray, BufferedIOBase, TextIOBase, Dict]

The GeoJSON data representing the polygon. - 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

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

Returns:

Type Description
GetPolygonDataResponse

A GetPolygonDataResponse object containing the data for the polygon.

get_polygon_stats(geojson, layer_ids, project_id=None)

Return statistics about a polygon encoded in GeoJSON.

Parameters:

Name Type Description Default
geojson Union[PathLike, str, bytes, bytearray, BufferedIOBase, TextIOBase, Dict]

The GeoJSON data representing the polygon. - 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

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

Returns:

Type Description
GetPolygonStatsResponse

A GetPolygonStatsResponse object containing the statistics for the polygon.

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)

Attempt 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

Returns:

Type Description
CreatePortfolioTaskResponse

A CreatePortfolioTaskResponse object containing the task details.

task_status(task_id)

Get the status of an existing portfolio task.

Parameters:

Name Type Description Default
task_id str

ID of previously created portfolio task

required

Returns:

Type Description
GetPortfolioTaskStatusResponse

A GetPortfolioTaskStatusResponse object containing the task status.

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

Upload 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_large_polygon(vector_file_name, layer_ids, project_id=None, *, correct_polygon_points_order=False)

Return data pertaining to a large 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

Returns:

Type Description
GetLargePolygonDataResponse

A GetLargePolygonDataResponse object containing the data for the large polygon.

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

Return 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

Returns:

Type Description
GetPolygonDataResponse

A GetPolygonDataResponse object containing the data for the polygon.

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

Return 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

Returns:

Type Description
GetPolygonStatsResponse

A GetPolygonStatsResponse object containing the statistics for the polygon.

point(lat, lng)

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

Parameters:

Name Type Description Default
lat float

The latitude of the point.

required
lng float

The longitude of the point.

required

Returns:

Type Description
Point

A Point object.

polygon(points)

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

Parameters:

Name Type Description Default
points List[Point]

A list of Point objects defining the polygon boundary.

required

Returns:

Type Description
Polygon

A Polygon object.

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

Write polygon tiff data from a 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'