Analytics

Analytics connectors: Google Analytics, Snowflake, data.world, Facebook Business.

Analytics Module — lazy-loaded.

Provides analytics integration: Google Analytics, Facebook Business, Snowflake, Data.world connectors, and Google Workspace write APIs (Sheets, Docs, Slides).

class siege_utilities.analytics.GoogleAnalyticsConnector[source]

Bases: object

Google Analytics connection and data retrieval manager.

__init__(client_id=None, client_secret=None, redirect_uri='urn:ietf:wg:oauth:2.0:oob', auth_method='oauth2', service_account_data=None)[source]

Initialize Google Analytics connector.

Parameters:
  • client_id (str) – OAuth2 client ID from Google Cloud Console (for OAuth2)

  • client_secret (str) – OAuth2 client secret from Google Cloud Console (for OAuth2)

  • redirect_uri (str) – OAuth2 redirect URI (for OAuth2)

  • auth_method (str) – Authentication method (“oauth2” or “service_account”)

  • service_account_data (Dict[str, Any]) – Service account credentials dict (for service account auth)

authenticate(token_file='ga_token.json')[source]

Authenticate with Google Analytics using OAuth2.

Parameters:

token_file (str) – Path to store/retrieve OAuth token

Raises:
  • google.auth.exceptions.* – On authentication failure.

  • OSError – If token file cannot be read/written.

Return type:

None

authenticate_service_account()[source]

Authenticate with Google Analytics using service account. Based on working implementation from GA project.

Raises:
  • ValueError – If no service account data is available.

  • google.auth.exceptions.* – On authentication failure.

  • OSError – If temp file operations fail.

Return type:

None

get_ga4_data(property_id, start_date, end_date, metrics, dimensions=None, row_limit=100000)[source]

Retrieve data from Google Analytics 4.

Parameters:
  • property_id (str) – GA4 property ID

  • start_date (str) – Start date as YYYY-MM-DD (also accepts the GA4 relative keywords today, yesterday, or NdaysAgo). Interpreted in the property’s configured timezone, not the caller’s local time — set this in the GA admin UI.

  • end_date (str) – End date, same format / TZ rules as start_date.

  • metrics (List[str]) – List of metrics to retrieve

  • dimensions (List[str]) – List of dimensions to retrieve

  • row_limit (int) – Maximum rows to retrieve

Returns:

Pandas DataFrame with GA4 data

Raises:

ValueError – If start_date / end_date is not a valid YYYY-MM-DD date or recognized GA4 relative keyword. Previously, malformed dates were forwarded raw to the GA API and returned an opaque 400 hours later in a batch run.

Return type:

pandas.DataFrame

get_ua_data(view_id, start_date, end_date, metrics, dimensions=None, max_results=100000)[source]

Retrieve data from Universal Analytics.

Parameters:
  • view_id (str) – UA view ID

  • start_date (str) – Start date (YYYY-MM-DD)

  • end_date (str) – End date (YYYY-MM-DD)

  • metrics (List[str]) – List of metrics to retrieve

  • dimensions (List[str]) – List of dimensions to retrieve

  • max_results (int) – Maximum results to retrieve

Returns:

Pandas DataFrame with UA data

Raises:

ValueError – If start_date / end_date is not a valid YYYY-MM-DD date or recognized GA relative keyword.

Return type:

pandas.DataFrame

save_as_pandas(df, output_path, format='parquet')[source]

Save DataFrame as Pandas format.

Parameters:
  • df (pandas.DataFrame) – Pandas DataFrame to save

  • output_path (str) – Output file path

  • format (str) – Output format (parquet, csv, excel, etc.)

Raises:
  • ValueError – If the format is unsupported.

  • OSError – If the file cannot be written.

Return type:

None

save_as_spark(df, output_path, spark_session=None)[source]

Save DataFrame as Spark DataFrame and optionally to storage.

Parameters:
  • df (pandas.DataFrame) – Pandas DataFrame to convert

  • output_path (str) – Output path for Spark DataFrame

  • spark_session (pyspark.sql.SparkSession | None) – Optional SparkSession (will create if not provided)

Raises:
  • ImportError – If PySpark is not available.

  • OSError – If the output path cannot be written.

Return type:

None

siege_utilities.analytics.create_ga_account_profile(client_id, ga_property_id, account_type='ga4', credentials_file=None)[source]

Create a Google Analytics account profile linked to a client.

Parameters:
  • client_id (str) – Client ID from client management system

  • ga_property_id (str) – Google Analytics property ID

  • account_type (str) – Type of GA account (ga4, ua, or both)

  • credentials_file (str) – Path to OAuth credentials file

Returns:

GA account profile dictionary

Return type:

Dict[str, Any]

siege_utilities.analytics.save_ga_account_profile(profile, config_directory='config')[source]

Save GA account profile to JSON file.

Parameters:
  • profile (Dict[str, Any]) – GA account profile dictionary

  • config_directory (str) – Directory to save config files

Returns:

Path to saved config file

Return type:

str

siege_utilities.analytics.load_ga_account_profile(account_id, config_directory='config')[source]

Load GA account profile from JSON file.

Parameters:
  • account_id (str) – GA account ID to load

  • config_directory (str) – Directory containing config files

Returns:

GA account profile dictionary or None if not found

Return type:

Dict[str, Any] | None

siege_utilities.analytics.list_ga_accounts_for_client(client_id, config_directory='config')[source]

List all GA accounts associated with a client.

Parameters:
  • client_id (str) – Client ID to search for

  • config_directory (str) – Directory containing config files

Returns:

List of GA account profiles

Return type:

List[Dict[str, Any]]

siege_utilities.analytics.batch_retrieve_ga_data(client_id, start_date, end_date, metrics, dimensions=None, output_format='pandas', output_directory='output/ga_data')[source]

Batch retrieve GA data for all accounts associated with a client.

Parameters:
  • client_id (str) – Client ID to retrieve data for

  • start_date (str) – Start date for data retrieval

  • end_date (str) – End date for data retrieval

  • metrics (List[str]) – List of metrics to retrieve

  • dimensions (List[str]) – List of dimensions to retrieve

  • output_format (str) – Output format (pandas, spark, or both)

  • output_directory (str) – Directory to save output files

Returns:

Dictionary with retrieval results

Return type:

Dict[str, Any]

siege_utilities.analytics.create_ga_connector_with_service_account(service_account_data=None)[source]

Create a GoogleAnalyticsConnector using service account authentication.

Parameters:

service_account_data (Dict[str, Any]) – Service account credentials dict (optional, will try 1Password if None)

Returns:

GoogleAnalyticsConnector instance configured for service account auth

Return type:

GoogleAnalyticsConnector

class siege_utilities.analytics.FacebookBusinessConnector[source]

Bases: object

Facebook Business connection and data retrieval manager.

__init__(access_token, app_id=None, app_secret=None)[source]

Initialize Facebook Business connector.

Parameters:
  • access_token (str) – Facebook access token

  • app_id (str) – Facebook app ID (optional)

  • app_secret (str) – Facebook app secret (optional)

get_ad_accounts()[source]

Get list of accessible ad accounts.

Returns:

List of ad account information

Return type:

List[Dict[str, Any]]

get_ad_insights(ad_account_id, start_date, end_date, fields=None, breakdowns=None)[source]

Retrieve ad insights from Facebook Ads.

Parameters:
  • ad_account_id (str) – Facebook ad account ID

  • start_date (str) – Start date (YYYY-MM-DD)

  • end_date (str) – End date (YYYY-MM-DD)

  • fields (List[str]) – List of insight fields to retrieve

  • breakdowns (List[str]) – List of breakdowns to apply

Returns:

Pandas DataFrame with ad insights

Return type:

pandas.DataFrame

get_page_insights(page_id, start_date, end_date, metrics=None)[source]

Retrieve page insights from Facebook Pages.

Parameters:
  • page_id (str) – Facebook page ID

  • start_date (str) – Start date (YYYY-MM-DD)

  • end_date (str) – End date (YYYY-MM-DD)

  • metrics (List[str]) – List of metrics to retrieve

Returns:

Pandas DataFrame with page insights

Return type:

pandas.DataFrame

get_business_insights(business_id, start_date, end_date, metrics=None)[source]

Retrieve business insights from Facebook Business Manager.

Parameters:
  • business_id (str) – Facebook business ID

  • start_date (str) – Start date (YYYY-MM-DD)

  • end_date (str) – End date (YYYY-MM-DD)

  • metrics (List[str]) – List of metrics to retrieve

Returns:

Pandas DataFrame with business insights

Return type:

pandas.DataFrame

save_as_pandas(df, output_path, format='parquet')[source]

Save DataFrame as Pandas format.

Parameters:
  • df (pandas.DataFrame) – Pandas DataFrame to save

  • output_path (str) – Output file path

  • format (str) – Output format (parquet, csv, excel, etc.)

Raises:
  • ValueError – If the format is unsupported.

  • OSError – If the file cannot be written.

Return type:

None

save_as_spark(df, output_path, spark_session=None)[source]

Save DataFrame as Spark DataFrame and optionally to storage.

Parameters:
  • df (pandas.DataFrame) – Pandas DataFrame to convert

  • output_path (str) – Output path for Spark DataFrame

  • spark_session (pyspark.sql.SparkSession | None) – Optional SparkSession (will create if not provided)

Raises:
  • ImportError – If PySpark is not available.

  • OSError – If the output path cannot be written.

Return type:

None

siege_utilities.analytics.create_facebook_account_profile(client_id, fb_account_id, account_type='ad_account', access_token=None)[source]

Create a Facebook account profile linked to a client.

Parameters:
  • client_id (str) – Client ID from client management system

  • fb_account_id (str) – Facebook account ID

  • account_type (str) – Type of FB account (ad_account, page, business)

  • access_token (str) – Facebook access token

Returns:

Facebook account profile dictionary

Return type:

Dict[str, Any]

siege_utilities.analytics.save_facebook_account_profile(profile, config_directory='config')[source]

Save Facebook account profile to JSON file.

Parameters:
  • profile (Dict[str, Any]) – Facebook account profile dictionary

  • config_directory (str) – Directory to save config files

Returns:

Path to saved config file

Return type:

str

siege_utilities.analytics.load_facebook_account_profile(account_id, config_directory='config')[source]

Load Facebook account profile from JSON file.

Parameters:
  • account_id (str) – Facebook account ID to load

  • config_directory (str) – Directory containing config files

Returns:

Facebook account profile dictionary or None if not found

Return type:

Dict[str, Any] | None

siege_utilities.analytics.list_facebook_accounts_for_client(client_id, config_directory='config')[source]

List all Facebook accounts associated with a client.

Parameters:
  • client_id (str) – Client ID to search for

  • config_directory (str) – Directory containing config files

Returns:

List of Facebook account profiles

Return type:

List[Dict[str, Any]]

siege_utilities.analytics.batch_retrieve_facebook_data(client_id, start_date, end_date, data_types=None, output_format='pandas', output_directory='output/facebook_data')[source]

Batch retrieve Facebook data for all accounts associated with a client.

Parameters:
  • client_id (str) – Client ID to retrieve data for

  • start_date (str) – Start date for data retrieval

  • end_date (str) – End date for data retrieval

  • data_types (List[str]) – Types of data to retrieve (ads, pages, business)

  • output_format (str) – Output format (pandas, spark, or both)

  • output_directory (str) – Directory to save output files

Returns:

Dictionary with retrieval results

Return type:

Dict[str, Any]

class siege_utilities.analytics.SnowflakeConnector[source]

Bases: object

Snowflake data warehouse connector with advanced features.

__init__(account, user, password=None, warehouse=None, database=None, schema=None, role=None, config_file=None)[source]

Initialize Snowflake connector.

Parameters:
  • account (str) – Snowflake account identifier

  • user (str) – Snowflake username

  • password (str | None) – Snowflake password (optional if using config file)

  • warehouse (str | None) – Default warehouse to use

  • database (str | None) – Default database to use

  • schema (str | None) – Default schema to use

  • role (str | None) – Default role to use

  • config_file (str | Path | None) – Path to configuration file

connect()[source]

Establish connection to Snowflake.

Raises:

ConnectionError – If the connection attempt fails.

Return type:

None

disconnect()[source]

Close Snowflake connection.

Return type:

None

execute_query(query, params=None)[source]

Execute a SQL query.

Parameters:
  • query (str) – SQL query string

  • params (Dict[str, Any] | None) – Query parameters (optional)

Returns:

Query results as list of tuples

Raises:
Return type:

List[tuple]

execute_ddl(ddl_statement)[source]

Execute DDL statements (CREATE, ALTER, DROP, etc.).

Parameters:

ddl_statement (str) – DDL SQL statement

Raises:
Return type:

None

upload_dataframe(df, table_name, database=None, schema=None, auto_create_table=True, overwrite=False)[source]

Upload pandas DataFrame to Snowflake table.

Parameters:
  • df (pd.DataFrame) – Pandas DataFrame to upload

  • table_name (str) – Target table name

  • database (str | None) – Target database (uses default if not specified)

  • schema (str | None) – Target schema (uses default if not specified)

  • auto_create_table (bool) – Whether to automatically create table if it doesn’t exist

  • overwrite (bool) – Whether to overwrite existing table

Raises:
Return type:

None

download_dataframe(query, params=None)[source]

Download data from Snowflake as pandas DataFrame.

Parameters:
  • query (str) – SQL query to execute

  • params (Dict[str, Any] | None) – Query parameters (optional)

Returns:

Pandas DataFrame with query results

Raises:
Return type:

pd.DataFrame

get_table_info(table_name, database=None, schema=None)[source]

Get information about a Snowflake table.

Parameters:
  • table_name (str) – Name of the table

  • database (str | None) – Database name (uses default if not specified)

  • schema (str | None) – Schema name (uses default if not specified)

Returns:

Dictionary with table information

Raises:
Return type:

Dict[str, Any]

list_tables(database=None, schema=None)[source]

List all tables in a database/schema.

Parameters:
  • database (str | None) – Database name (uses default if not specified)

  • schema (str | None) – Schema name (uses default if not specified)

Returns:

List of table names

Raises:
Return type:

List[str]

siege_utilities.analytics.get_snowflake_connector(config_file=None)[source]

Get Snowflake connector instance from configuration.

Parameters:

config_file (str | Path | None)

Return type:

SnowflakeConnector

siege_utilities.analytics.upload_to_snowflake(df, table_name, config_file=None, **kwargs)[source]

Convenience function to upload DataFrame to Snowflake.

Parameters:
  • df (pd.DataFrame) – Pandas DataFrame to upload.

  • table_name (str) – Target table name.

  • config_file (str | Path | None) – Path to configuration file (optional).

  • **kwargs – Forwarded to SnowflakeConnector.upload_dataframe(). See that method for accepted parameters.

Return type:

None

siege_utilities.analytics.download_from_snowflake(query, config_file=None, **kwargs)[source]

Convenience function to download DataFrame from Snowflake.

Parameters:
  • query (str) – SQL query to execute.

  • config_file (str | Path | None) – Path to configuration file (optional).

  • **kwargs – Forwarded to SnowflakeConnector.download_dataframe(). See that method for accepted parameters.

Return type:

pd.DataFrame

siege_utilities.analytics.execute_snowflake_query(query, config_file=None, **kwargs)[source]

Convenience function to execute Snowflake query.

Parameters:
  • query (str) – SQL query string.

  • config_file (str | Path | None) – Path to configuration file (optional).

  • **kwargs – Forwarded to SnowflakeConnector.execute_query(). See that method for accepted parameters.

Return type:

List[tuple]

class siege_utilities.analytics.DataDotWorldConnector[source]

Bases: object

Data.world connector with advanced data discovery and access features.

__init__(api_token=None, config_file=None)[source]

Initialize Data.world connector.

Parameters:
  • api_token (str | None) – Data.world API token (optional if using config file)

  • config_file (str | Path | None) – Path to configuration file

search_datasets(query, limit=50, owner=None, tags=None)[source]

Search for datasets on data.world.

Parameters:
  • query (str) – Search query string

  • limit (int) – Maximum number of results to return

  • owner (str | None) – Filter by dataset owner

  • tags (List[str] | None) – Filter by tags

Returns:

List of dataset information dictionaries

Raises:

ConnectionError – If the API request fails.

Return type:

List[Dict[str, Any]]

get_dataset_info(dataset_id)[source]

Get detailed information about a specific dataset.

Parameters:

dataset_id (str) – Dataset identifier (format: owner/dataset)

Returns:

Dictionary with detailed dataset information

Raises:

ConnectionError – If the API request fails.

Return type:

Dict[str, Any]

list_dataset_files(dataset_id)[source]

List all files in a dataset.

Parameters:

dataset_id (str) – Dataset identifier (format: owner/dataset)

Returns:

List of file information dictionaries

Raises:

ConnectionError – If the API request fails.

Return type:

List[Dict[str, Any]]

download_file(dataset_id, file_name, output_path=None)[source]

Download a specific file from a dataset.

Parameters:
  • dataset_id (str) – Dataset identifier (format: owner/dataset)

  • file_name (str) – Name of the file to download

  • output_path (str | Path | None) – Local path to save the file (optional)

Returns:

Path to the downloaded file

Raises:
Return type:

Path

load_dataset_as_dataframe(dataset_id, file_name=None)[source]

Load a dataset file directly as a pandas DataFrame.

Parameters:
  • dataset_id (str) – Dataset identifier (format: owner/dataset)

  • file_name (str | None) – Name of the file to load (optional, loads first file if not specified)

Returns:

Pandas DataFrame with the data

Raises:
Return type:

pd.DataFrame

query_dataset(dataset_id, query, query_type='sql')[source]

Execute a query against a dataset.

Parameters:
  • dataset_id (str) – Dataset identifier (format: owner/dataset)

  • query (str) – Query string (SQL or SPARQL)

  • query_type (str) – Type of query (‘sql’ or ‘sparql’)

Returns:

Pandas DataFrame with query results

Raises:
Return type:

pd.DataFrame

get_dataset_schema(dataset_id)[source]

Get the schema information for a dataset.

Parameters:

dataset_id (str) – Dataset identifier (format: owner/dataset)

Returns:

Dictionary with schema information

Raises:

ConnectionError – If the API request fails.

Return type:

Dict[str, Any]

create_dataset(owner, dataset_id, title, description, tags=None, license='Public Domain', visibility='OPEN')[source]

Create a new dataset on data.world.

Parameters:
  • owner (str) – Dataset owner username

  • dataset_id (str) – Unique dataset identifier

  • title (str) – Dataset title

  • description (str) – Dataset description

  • tags (List[str] | None) – List of tags (optional)

  • license (str) – Dataset license (optional)

  • visibility (str) – Dataset visibility (‘OPEN’ or ‘PRIVATE’)

Returns:

owner/dataset_id)

Return type:

Created dataset ID (format

Raises:
upload_file(dataset_id, file_path, file_name=None)[source]

Upload a file to an existing dataset.

Parameters:
  • dataset_id (str) – Dataset identifier (format: owner/dataset)

  • file_path (str | Path) – Local path to the file to upload

  • file_name (str | None) – Name to use for the file on data.world (optional)

Raises:
Return type:

None

update_dataset(dataset_id, title=None, description=None, tags=None, license=None)[source]

Update an existing dataset.

Parameters:
  • dataset_id (str) – Dataset identifier (format: owner/dataset)

  • title (str | None) – New title (optional)

  • description (str | None) – New description (optional)

  • tags (List[str] | None) – New tags (optional)

  • license (str | None) – New license (optional)

Raises:
Return type:

None

delete_dataset(dataset_id)[source]

Delete a dataset.

Parameters:

dataset_id (str) – Dataset identifier (format: owner/dataset)

Raises:
Return type:

None

siege_utilities.analytics.get_datadotworld_connector(config_file=None)[source]

Get Data.world connector instance from configuration.

Parameters:

config_file (str | Path | None)

Return type:

DataDotWorldConnector

siege_utilities.analytics.search_datasets(query, config_file=None, **kwargs)[source]

Standalone function to search for datasets.

Parameters:
  • query (str) – Search query string

  • config_file (str | Path | None) – Path to configuration file (optional)

  • **kwargs – Additional search parameters

Returns:

List of matching datasets

Return type:

List[Dict[str, Any]]

siege_utilities.analytics.list_datasets(limit=50, config_file=None, **kwargs)[source]

Standalone function to list available datasets.

Parameters:
  • limit (int) – Maximum number of results to return

  • config_file (str | Path | None) – Optional configuration file path

  • **kwargs – Additional arguments to pass to search_datasets

Returns:

List of dataset information dictionaries

Return type:

List[Dict[str, Any]]

siege_utilities.analytics.search_datadotworld_datasets(query, config_file=None, **kwargs)[source]

Convenience function to search for datasets.

Parameters:
  • query (str) – Search query string.

  • config_file (str | Path | None) – Path to configuration file (optional).

  • **kwargs – Forwarded to DataDotWorldConnector.search_datasets(). See that method for accepted parameters.

Return type:

List[Dict[str, Any]]

siege_utilities.analytics.load_datadotworld_dataset(dataset_id, config_file=None, **kwargs)[source]

Convenience function to load a dataset as DataFrame.

Parameters:
  • dataset_id (str) – Dataset identifier (format: owner/dataset).

  • config_file (str | Path | None) – Path to configuration file (optional).

  • **kwargs – Forwarded to DataDotWorldConnector.load_dataset_as_dataframe(). See that method for accepted parameters.

Return type:

pd.DataFrame

siege_utilities.analytics.query_datadotworld_dataset(dataset_id, query, config_file=None, **kwargs)[source]

Convenience function to query a dataset.

Parameters:
  • dataset_id (str) – Dataset identifier (format: owner/dataset).

  • query (str) – Query string (SQL or SPARQL).

  • config_file (str | Path | None) – Path to configuration file (optional).

  • **kwargs – Forwarded to DataDotWorldConnector.query_dataset(). See that method for accepted parameters.

Return type:

pd.DataFrame

class siege_utilities.analytics.GoogleWorkspaceClient[source]

Bases: object

Authenticated client that builds Google API service objects.

Do not instantiate directly — use the from_oauth() or from_service_account() class methods.

__init__(credentials)[source]
classmethod from_oauth(client_id, client_secret, token_file=None, redirect_uri='urn:ietf:wg:oauth:2.0:oob', scopes=None)[source]

Authenticate via OAuth2 interactive flow.

If token_file exists and contains a valid/refreshable token, no browser interaction is needed.

Parameters:
Return type:

GoogleWorkspaceClient

classmethod from_1password(item_title='Google OAuth Client - siege_utilities', vault=None, account='TLTQ3ANAABGCNEK7KIAOTDNK2Q', token_file=None, scopes=None)[source]

Authenticate using credentials stored in a 1Password Document item.

Auto-detects whether the JSON document is an OAuth client secret (has "installed" or "web" key) or a service account key (has "type": "service_account"), and routes to the appropriate auth flow.

For OAuth: runs the installed-app flow (browser required on first use; cached token reused afterward).

For service account: authenticates server-to-server with no browser interaction.

Parameters:
  • item_title (str) – Title of the 1Password Document item.

  • vault (str | None) – 1Password vault name.

  • account (str | None) – 1Password account shorthand or UUID.

  • token_file (str | Path | None) – Path to cache the OAuth token (ignored for service accounts). Default: ~/.siege/tokens/workspace_token.json.

  • scopes (List[str] | None) – OAuth scopes (defaults to WORKSPACE_SCOPES).

Returns:

Authenticated GoogleWorkspaceClient.

Return type:

GoogleWorkspaceClient

classmethod from_service_account(service_account_data=None, service_account_file=None, scopes=None)[source]

Authenticate via service account credentials.

Provide service_account_data (dict) or service_account_file (path). If neither is given, attempts to fetch from 1Password via CredentialManager.get_google_service_account_from_1password().

Parameters:
Return type:

GoogleWorkspaceClient

classmethod from_credentials(credentials)[source]

Wrap an already-authenticated google.auth.credentials.Credentials.

Return type:

GoogleWorkspaceClient

classmethod from_account(account, person=None, scopes=None)[source]

Build a client from a GoogleAccount.

For OAuth accounts the method looks for a cached token_file first, then resolves oauth_integration_name from person to get client_id/client_secret for the OAuth flow.

For service accounts the method resolves service_account_ref via CredentialManager (1Password) or treats it as a file path.

Parameters:
Return type:

GoogleWorkspaceClient

classmethod from_registry(registry, google_account_id=None, person=None, scopes=None)[source]

Build a client from a registry’s default or specified account.

If google_account_id is given, looks it up directly; otherwise uses the registry’s default account.

Parameters:
Return type:

GoogleWorkspaceClient

sheets_service()[source]

Return the Google Sheets API v4 service object.

docs_service()[source]

Return the Google Docs API v1 service object.

slides_service()[source]

Return the Google Slides API v1 service object.

drive_service()[source]

Return the Google Drive API v3 service object.

property credentials
batch_update_spreadsheet(spreadsheet_id, requests)[source]

Execute a batch of Sheets API requests.

Parameters:
  • spreadsheet_id (str) – Target spreadsheet ID.

  • requests (List[Dict[str, Any]]) – List of request dicts per the Sheets API batchUpdate spec.

Returns:

The API response dict.

Return type:

Dict[str, Any]

batch_update_document(document_id, requests)[source]

Execute a batch of Docs API requests.

Parameters:
  • document_id (str) – Target document ID.

  • requests (List[Dict[str, Any]]) – List of request dicts per the Docs API batchUpdate spec.

Returns:

The API response dict.

Return type:

Dict[str, Any]

batch_update_presentation(presentation_id, requests)[source]

Execute a batch of Slides API requests.

Parameters:
  • presentation_id (str) – Target presentation ID.

  • requests (List[Dict[str, Any]]) – List of request dicts per the Slides API batchUpdate spec.

Returns:

The API response dict.

Return type:

Dict[str, Any]

static spreadsheet_url(spreadsheet_id)[source]

Return the live Google Sheets URL for a spreadsheet ID.

Parameters:

spreadsheet_id (str)

Return type:

str

static document_url(document_id)[source]

Return the live Google Docs URL for a document ID.

Parameters:

document_id (str)

Return type:

str

static presentation_url(presentation_id)[source]

Return the live Google Slides URL for a presentation ID.

Parameters:

presentation_id (str)

Return type:

str

static file_url(file_id, mime_type=None)[source]

Return the live Google Drive URL for a file ID.

If mime_type is provided, returns the appropriate editor URL. Otherwise returns the generic Drive file URL.

Parameters:
  • file_id (str)

  • mime_type (str | None)

Return type:

str

copy_file(file_id, title=None)[source]

Copy a Drive file (spreadsheet, doc, presentation) and return the new ID.

Parameters:
  • file_id (str) – The ID of the file to copy.

  • title (str | None) – Optional title for the copy. None keeps the default “Copy of …” naming.

Returns:

The new file’s ID.

Return type:

str

share_file(file_id, email, role='writer', send_notification=False)[source]

Share a Drive file with a user.

Parameters:
  • file_id (str) – The file to share.

  • email (str) – Email address of the recipient.

  • role (str) – "reader", "writer", or "commenter".

  • send_notification (bool) – Whether to send an email notification.

Returns:

The permission resource dict.

Return type:

Dict[str, Any]

move_to_folder(file_id, folder_id)[source]

Move a file into a Drive folder.

Parameters:
  • file_id (str) – The file to move.

  • folder_id (str) – Target folder ID.

Returns:

The updated file resource dict.

Return type:

Dict[str, Any]

siege_utilities.analytics.create_spreadsheet(client, title, sheet_names=None, folder_id=None)[source]

Create a new Google Spreadsheet and return its ID.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • title (str) – Title for the new spreadsheet.

  • sheet_names (List[str] | None) – Optional list of sheet/tab names to create. If omitted, a single default “Sheet1” is created.

  • folder_id (str | None) – Optional Drive folder ID to create the spreadsheet in.

Returns:

The spreadsheet ID string.

Return type:

str

siege_utilities.analytics.write_values(client, spreadsheet_id, range_, values, value_input_option='USER_ENTERED')[source]

Write a 2-D list of values to a range.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • spreadsheet_id (str) – Target spreadsheet ID.

  • range – A1 notation range (e.g. "Sheet1!A1:D10").

  • values (List[List[Any]]) – Row-major list of lists.

  • value_input_option (str) – "RAW" or "USER_ENTERED" (default).

  • range_ (str)

Returns:

The API response dict.

Return type:

Dict[str, Any]

siege_utilities.analytics.append_rows(client, spreadsheet_id, range_, values, value_input_option='USER_ENTERED')[source]

Append rows after existing data in a range.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • spreadsheet_id (str) – Target spreadsheet ID.

  • range – A1 notation range to search for a table (e.g. "Sheet1").

  • values (List[List[Any]]) – Row-major list of lists to append.

  • value_input_option (str) – "RAW" or "USER_ENTERED" (default).

  • range_ (str)

Returns:

The API response dict.

Return type:

Dict[str, Any]

siege_utilities.analytics.read_values(client, spreadsheet_id, range_)[source]

Read values from a range.

Returns:

Row-major list of lists (may be ragged).

Parameters:
  • spreadsheet_id (str)

  • range_ (str)

Return type:

List[List[Any]]

siege_utilities.analytics.write_dataframe(client, spreadsheet_id, df, sheet_name='Sheet1', include_header=True, start_cell='A1')[source]

Write a pandas DataFrame to a sheet.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • spreadsheet_id (str) – Target spreadsheet ID.

  • df – pandas DataFrame to write.

  • sheet_name (str) – Tab name (default "Sheet1").

  • include_header (bool) – Whether to include column names as first row.

  • start_cell (str) – Top-left cell (default "A1").

Returns:

The API response dict.

Return type:

Dict[str, Any]

siege_utilities.analytics.read_dataframe(client, spreadsheet_id, range_='Sheet1', has_header=True)[source]

Read a range from a spreadsheet into a pandas DataFrame.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • spreadsheet_id (str) – Source spreadsheet ID.

  • range – A1 notation range (e.g. "Sheet1" or "Sheet1!A1:D100").

  • has_header (bool) – If True, first row is used as column names.

  • range_ (str)

Returns:

pandas DataFrame.

siege_utilities.analytics.add_sheet(client, spreadsheet_id, title)[source]

Add a new tab/sheet to an existing spreadsheet.

Returns:

The new sheet ID (integer).

Parameters:
  • spreadsheet_id (str)

  • title (str)

Return type:

int

siege_utilities.analytics.get_spreadsheet_metadata(client, spreadsheet_id)[source]

Fetch spreadsheet metadata (title, sheets, locale, etc.).

Returns:

The spreadsheet resource dict.

Parameters:

spreadsheet_id (str)

Return type:

Dict[str, Any]

siege_utilities.analytics.copy_spreadsheet(client, spreadsheet_id, title=None)[source]

Copy an entire spreadsheet via the Drive API.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • spreadsheet_id (str) – Source spreadsheet ID.

  • title (str | None) – Title for the copy (default: “Copy of …”).

Returns:

The new spreadsheet ID.

Return type:

str

siege_utilities.analytics.create_presentation(client, title, folder_id=None)[source]

Create a new Google Slides presentation and return its ID.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • title (str) – Title for the new presentation.

  • folder_id (str | None) – Optional Drive folder ID to create the presentation in.

Returns:

The presentation ID string.

Return type:

str

siege_utilities.analytics.get_presentation(client, presentation_id)[source]

Fetch full presentation metadata.

Returns:

The presentation resource dict.

Parameters:

presentation_id (str)

Return type:

Dict[str, Any]

siege_utilities.analytics.copy_presentation(client, presentation_id, title=None)[source]

Copy an entire presentation via the Drive API.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • presentation_id (str) – Source presentation ID.

  • title (str | None) – Title for the copy (default: “Copy of …”).

Returns:

The new presentation ID.

Return type:

str

siege_utilities.analytics.add_blank_slide(client, presentation_id, layout='BLANK', insertion_index=None)[source]

Add a blank slide to a presentation.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • presentation_id (str) – Target presentation ID.

  • layout (str) – Predefined layout ("BLANK", "TITLE", "TITLE_AND_BODY", etc.).

  • insertion_index (int | None) – Position (0-based). None appends at end.

Returns:

The new slide’s object ID.

Return type:

str

siege_utilities.analytics.create_textbox(client, presentation_id, slide_id, text, left=100, top=100, width=400, height=50)[source]

Create a text box on a slide and populate it with text.

Dimensions are in EMU (English Metric Units). 1 inch = 914400 EMU. For convenience, this function accepts points (1 pt = 12700 EMU) but the values are treated as points internally.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • presentation_id (str) – Target presentation ID.

  • slide_id (str) – Slide object ID.

  • text (str) – Text to put in the box.

  • left (float) – Position in points from top-left.

  • top (float) – Position in points from top-left.

  • width (float) – Dimensions in points.

  • height (float) – Dimensions in points.

Returns:

The textbox object ID.

Return type:

str

siege_utilities.analytics.create_document(client, title, folder_id=None)[source]

Create a new Google Doc and return its document ID.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • title (str) – Title for the new document.

  • folder_id (str | None) – Optional Drive folder ID to create the document in.

Returns:

The document ID string.

Return type:

str

siege_utilities.analytics.get_document(client, document_id)[source]

Fetch full document metadata and content structure.

Returns:

The document resource dict.

Parameters:

document_id (str)

Return type:

Dict[str, Any]

siege_utilities.analytics.copy_document(client, document_id, title=None)[source]

Copy a document via the Drive API.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • document_id (str) – Source document ID.

  • title (str | None) – Title for the copy (default: “Copy of …”).

Returns:

The new document ID.

Return type:

str

siege_utilities.analytics.read_document_text(client, document_id)[source]

Read the full plain-text content of a document.

Extracts text from all structural elements (paragraphs, tables, etc.).

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • document_id (str) – Target document ID.

Returns:

The document text as a single string.

Return type:

str

siege_utilities.analytics.insert_paragraph(client, document_id, text, index=1, heading=None)[source]

Insert a paragraph with optional heading style.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • document_id (str) – Target document ID.

  • text (str) – Paragraph text (newline is appended automatically).

  • index (int) – Character index (1-based).

  • heading (str | None) – Named style ("HEADING_1" through "HEADING_6", "TITLE", "SUBTITLE", or None for normal text).

Returns:

The API response dict.

Return type:

Dict[str, Any]

siege_utilities.analytics.insert_table(client, document_id, rows, cols, index=1)[source]

Insert an empty table at the given index.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • document_id (str) – Target document ID.

  • rows (int) – Number of rows.

  • cols (int) – Number of columns.

  • index (int) – Character index where the table is inserted.

Returns:

The API response dict.

Return type:

Dict[str, Any]

siege_utilities.analytics.replace_text(client, document_id, find, replace_with, match_case=True)[source]

Find and replace text throughout a document.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • document_id (str) – Target document ID.

  • find (str) – Text to search for.

  • replace_with (str) – Replacement text.

  • match_case (bool) – Whether the search is case-sensitive.

Returns:

The API response dict.

Return type:

Dict[str, Any]

class siege_utilities.analytics.VistaSocialConnector[source]

Bases: object

Bearer-token authenticated client for the Vista Social REST API.

Usage:

from siege_utilities.analytics.vista_social import VistaSocialConnector

client = VistaSocialConnector(api_token=os.environ["VISTA_SOCIAL_TOKEN"])
accounts = client.list_accounts()
analytics = client.get_account_analytics(
    account_id=accounts[0]["id"],
    start_date="2026-01-01",
    end_date="2026-01-31",
)

All methods raise:

The connector follows the project’s failure-mode discipline (see docs/FAILURE_MODES.md): no method silently returns an empty dict on failure. Every failure mode is either a typed exception or a None return with a documented meaning.

__init__(api_token, *, base_url='https://api.vistasocial.com', timeout=30, retry_attempts=3, retry_backoff=1.5)[source]
Parameters:
Return type:

None

close()[source]

Close the underlying HTTP session.

Return type:

None

list_accounts()[source]

Return the list of accounts this token can access.

Wraps GET /v1/accounts. Returns the decoded data list from the response, or an empty list if the API returned nothing. Raises on auth / rate-limit / network failures (no silent empty-on-error).

Return type:

List[Mapping[str, Any]]

list_profiles(account_id)[source]

Return social profiles connected to account_id.

Wraps GET /v1/accounts/{account_id}/profiles.

Parameters:

account_id (str)

Return type:

List[Mapping[str, Any]]

get_account_analytics(account_id, *, start_date, end_date, metrics=None)[source]

Fetch aggregate analytics for account_id over a date range.

Parameters:
  • account_id (str) – Vista Social account id (string, opaque).

  • start_date (str) – ISO-8601 date (YYYY-MM-DD), inclusive.

  • end_date (str) – ISO-8601 date, inclusive.

  • metrics (List[str] | None) – Optional list of metric names (e.g. ["impressions", "engagements", "reach", "follower_count"]). If omitted, Vista Social returns its default metric set.

Return type:

Dict[str, Any]

Wraps GET /v1/accounts/{account_id}/analytics. Returns the decoded JSON body verbatim – Vista Social returns a structured document with metric breakdowns; consumers can extract what they need.

list_posts(account_id, *, start_date=None, end_date=None, limit=100)[source]

Return posts for account_id with optional date filtering.

Wraps GET /v1/accounts/{account_id}/posts. Pagination is intentionally simple here – consumers that need full enumeration should call repeatedly with adjusted date ranges or extend this connector with cursor handling once the real API spec is known.

Parameters:
  • account_id (str)

  • start_date (str | None)

  • end_date (str | None)

  • limit (int)

Return type:

List[Mapping[str, Any]]

class siege_utilities.analytics.VistaSocialResponse[source]

Bases: object

Structured response from a Vista Social API call.

The connector returns this rather than the raw requests.Response so consumers don’t need to know about the underlying HTTP library.

status_code

HTTP status code (200 / 201 etc.).

Type:

int

data

Parsed JSON body. Empty dict if the response had no body (e.g. 204 No Content) or wasn’t JSON-decodable.

Type:

Mapping[str, Any]

headers

Response headers – useful for inspecting rate-limit counters (X-RateLimit-Remaining, Retry-After).

Type:

Mapping[str, str]

url

The fully-qualified URL that was called, for logging.

Type:

str

status_code: int
data: Mapping[str, Any]
headers: Mapping[str, str]
url: str = ''
__init__(status_code, data, headers=<factory>, url='')
Parameters:
Return type:

None

exception siege_utilities.analytics.VistaSocialError[source]

Bases: RuntimeError

Base class for all Vista Social connector failures.

exception siege_utilities.analytics.VistaSocialAuthError[source]

Bases: VistaSocialError

Authentication failed (401/403). Token is missing, wrong, or expired.

exception siege_utilities.analytics.VistaSocialRateLimitError[source]

Bases: VistaSocialError

API rate limit hit (429). Caller can back off and retry later.

class siege_utilities.analytics.Dimension[source]

Bases: object

A scoring dimension with a name and weight (0-100).

name: str
weight: float
__init__(name, weight)
Parameters:
Return type:

None

class siege_utilities.analytics.ThresholdConfig[source]

Bases: object

Tier thresholds for score classification.

Scores >= green_min are Green, >= yellow_min are Yellow, else Red.

green_min: float = 70.0
yellow_min: float = 40.0
classify(score)[source]
Parameters:

score (float)

Return type:

str

__init__(green_min=70.0, yellow_min=40.0)
Parameters:
Return type:

None

class siege_utilities.analytics.EntityScore[source]

Bases: object

Result of scoring an entity.

entity_id: str
composite_score: float
tier: str
dimension_scores: dict[str, float]
segment: str | None = None
trend: float | None = None
trend_direction: str | None = None
__init__(entity_id, composite_score, tier, dimension_scores, segment=None, trend=None, trend_direction=None)
Parameters:
Return type:

None

class siege_utilities.analytics.HealthScorer[source]

Bases: object

Weighted multi-dimensional entity scorer.

Parameters:
  • dimensions (list[Dimension]) – Scoring dimensions. Weights must sum to 100.

  • default_thresholds (ThresholdConfig, optional) – Default tier thresholds. Can be overridden per-segment.

  • segment_thresholds (dict[str, ThresholdConfig], optional) – Per-segment threshold overrides.

Raises:

ValueError – If dimensions is empty or weights don’t sum to 100.

__init__(dimensions, default_thresholds=None, segment_thresholds=None)[source]
Parameters:
Return type:

None

property dimension_names: list[str]
score(entity_id, scores, *, segment=None, previous_score=None)[source]

Score an entity across all dimensions.

Parameters:
  • entity_id (str) – Identifier for the entity being scored.

  • scores (dict[str, float]) – Per-dimension scores (0-100). Must include all dimensions.

  • segment (str, optional) – Segment for threshold selection.

  • previous_score (float, optional) – Previous composite score for trend detection.

Return type:

EntityScore

Raises:

ValueError – If scores dict is missing dimensions or values are out of range.

score_batch(entities)[source]

Score multiple entities.

Each dict must have ‘entity_id’ and ‘scores’ keys. Optional: ‘segment’, ‘previous_score’.

Parameters:

entities (list[dict]) – List of entity dicts with keys: entity_id, scores, and optionally segment, previous_score.

Return type:

list[EntityScore]

Raises:

ValueError – If any entity dict is missing required keys.

class siege_utilities.analytics.SignalType[source]

Bases: Enum

Types of risk signals.

DECLINE = 'decline'
THRESHOLD = 'threshold'
ABSENCE = 'absence'
ANOMALY = 'anomaly'
class siege_utilities.analytics.RiskTier[source]

Bases: Enum

Risk classification tiers, ordered by severity.

CRITICAL = 'Critical'
HIGH = 'High'
MEDIUM = 'Medium'
LOW = 'Low'
class siege_utilities.analytics.RiskSignal[source]

Bases: object

A named risk signal with type and weight.

Parameters:
  • name (str) – Signal identifier.

  • signal_type (SignalType) – Category of risk this signal measures.

  • weight (float) – Relative weight (0, 100]. All signals’ weights must sum to 100.

name: str
signal_type: SignalType
weight: float
__init__(name, signal_type, weight)
Parameters:
Return type:

None

class siege_utilities.analytics.RiskTierConfig[source]

Bases: object

Thresholds for risk tier classification.

Scores >= critical_min are Critical, >= high_min are High, etc.

critical_min: float = 80.0
high_min: float = 60.0
medium_min: float = 40.0
classify(score)[source]
Parameters:

score (float)

Return type:

RiskTier

__init__(critical_min=80.0, high_min=60.0, medium_min=40.0)
Parameters:
Return type:

None

class siege_utilities.analytics.RiskAssessment[source]

Bases: object

Result of a risk assessment.

entity_id: str
composite_score: float
tier: RiskTier
signal_scores: dict[str, float]
signal_types: dict[str, SignalType]
intervention: str | None = None
__init__(entity_id, composite_score, tier, signal_scores, signal_types, intervention=None)
Parameters:
Return type:

None

class siege_utilities.analytics.RiskAnalyzer[source]

Bases: object

Multi-signal risk stacking engine.

Parameters:
  • signals (list[RiskSignal]) – Risk signals to evaluate. Weights must sum to 100.

  • tier_config (RiskTierConfig, optional) – Tier classification thresholds.

  • interventions (dict[RiskTier, str], optional) – Mapping from risk tier to recommended intervention.

Raises:

ValueError – If signals is empty or weights don’t sum to 100.

__init__(signals, tier_config=None, interventions=None)[source]
Parameters:
Return type:

None

property signal_names: list[str]
assess(entity_id, scores)[source]

Assess risk for an entity.

Parameters:
  • entity_id (str) – Identifier for the entity.

  • scores (dict[str, float]) – Per-signal risk scores (0-100). Higher = more risk.

Return type:

RiskAssessment

Raises:

ValueError – If scores dict is missing signals or values are out of range.

assess_batch(entities)[source]

Assess risk for multiple entities.

Each dict must have ‘entity_id’ and ‘scores’ keys.

Return type:

list[RiskAssessment]

Parameters:

entities (list[dict[str, Any]])

class siege_utilities.analytics.DimensionScore[source]

Bases: object

A score for one entity on one dimension.

Parameters:
  • score (int) – Score on a 1-5 scale.

  • evidence (str) – Citation supporting the score (URL, doc reference, test result).

score: int
evidence: str
__init__(score, evidence)
Parameters:
Return type:

None

class siege_utilities.analytics.ComparisonResult[source]

Bases: object

Result of comparing entities across dimensions.

dimensions: list[str]
entities: list[str]
scores: dict[str, dict[str, DimensionScore]]
weighted_totals: dict[str, float]
gap_analysis: list[tuple[str, float]]
__init__(dimensions, entities, scores, weighted_totals, gap_analysis)
Parameters:
Return type:

None

class siege_utilities.analytics.FeatureMatrix[source]

Bases: object

Boolean feature support matrix with coverage scoring.

entities: list[str]
features: list[str]
matrix: dict[str, dict[str, bool]]
coverage: dict[str, float]
__init__(entities, features, matrix, coverage)
Parameters:
Return type:

None

class siege_utilities.analytics.ComparativeAnalyzer[source]

Bases: object

N-entity x M-dimension comparison engine.

Parameters:
  • dimensions (list[str]) – Dimension names for comparison.

  • weights (dict[str, float] | None) – Optional dimension weights. If provided, must cover all dimensions. If omitted, equal weights are used.

Raises:

ValueError – If dimensions is empty or weights don’t match dimensions.

__init__(dimensions, weights=None)[source]
Parameters:
Return type:

None

compare(entity_scores)[source]

Compare entities across all dimensions.

Parameters:

entity_scores (dict[str, dict[str, DimensionScore]]) – Outer key = entity name, inner key = dimension name.

Return type:

ComparisonResult

Raises:

ValueError – If any entity is missing a dimension score.

static build_feature_matrix(entity_features)[source]

Build a boolean feature support matrix with coverage scores.

Parameters:

entity_features (dict[str, dict[str, bool]]) – Outer key = entity name, inner key = feature name.

Return type:

FeatureMatrix

Raises:

ValueError – If no entities or no features are provided.

class siege_utilities.analytics.ForecastAccuracy[source]

Bases: object

Result of a forecast accuracy calculation.

mape: float
bias: float
bias_direction: str
grade: str
n_observations: int
n_excluded: int
__init__(mape, bias, bias_direction, grade, n_observations, n_excluded)
Parameters:
Return type:

None

class siege_utilities.analytics.CategoryBreakdown[source]

Bases: object

Per-category forecast accuracy.

category: str
accuracy: ForecastAccuracy
__init__(category, accuracy)
Parameters:
Return type:

None

class siege_utilities.analytics.TrendPoint[source]

Bases: object

Accuracy at a single time period.

period: str
mape: float
bias: float
__init__(period, mape, bias)
Parameters:
Return type:

None

class siege_utilities.analytics.ForecastReport[source]

Bases: object

Complete forecast accuracy report.

overall: ForecastAccuracy
by_category: list[CategoryBreakdown]
trend: list[TrendPoint]
trend_direction: str | None
__init__(overall, by_category, trend, trend_direction)
Parameters:
Return type:

None

class siege_utilities.analytics.ForecastAnalyzer[source]

Bases: object

Forecast accuracy engine.

Parameters:
  • actuals (list[float]) – Actual observed values.

  • forecasts (list[float]) – Forecasted values (same length as actuals).

  • categories (list[str] | None) – Optional category labels for per-category breakdown.

  • periods (list[str] | None) – Optional time period labels for trend analysis.

Raises:

ValueError – If inputs have mismatched lengths or are empty.

__init__(actuals, forecasts, categories=None, periods=None)[source]
Parameters:
Return type:

None

analyze()[source]

Run full forecast accuracy analysis.

Return type:

ForecastReport

class siege_utilities.analytics.PipelineItem[source]

Bases: object

A single item in the pipeline.

Parameters:
  • item_id (str) – Unique identifier.

  • stage (str) – Current pipeline stage.

  • value (float) – Item value (dollars, record count, etc.).

  • entered_stage (datetime | None) – When the item entered this stage. Required for velocity metrics.

item_id: str
stage: str
value: float
entered_stage: datetime | None = None
__init__(item_id, stage, value, entered_stage=None)
Parameters:
Return type:

None

class siege_utilities.analytics.StageMetrics[source]

Bases: object

Metrics for a single pipeline stage.

stage: str
count: int
total_value: float
avg_value: float
__init__(stage, count, total_value, avg_value)
Parameters:
Return type:

None

class siege_utilities.analytics.ConversionRate[source]

Bases: object

Conversion rate between consecutive stages.

from_stage: str
to_stage: str
rate: float
from_count: int
to_count: int
__init__(from_stage, to_stage, rate, from_count, to_count)
Parameters:
Return type:

None

class siege_utilities.analytics.VelocityMetrics[source]

Bases: object

Time-in-stage metrics.

stage: str
avg_days: float
max_days: float
aging_items: list[str]
__init__(stage, avg_days, max_days, aging_items)
Parameters:
Return type:

None

class siege_utilities.analytics.ConcentrationAlert[source]

Bases: object

Alert when a single item dominates the pipeline.

item_id: str
share: float
stage: str
value: float
__init__(item_id, share, stage, value)
Parameters:
Return type:

None

class siege_utilities.analytics.PipelineReport[source]

Bases: object

Complete pipeline health report.

coverage_ratio: float | None
stage_metrics: list[StageMetrics]
conversions: list[ConversionRate]
velocity: list[VelocityMetrics]
concentration_alerts: list[ConcentrationAlert]
total_value: float
target: float | None
__init__(coverage_ratio, stage_metrics, conversions, velocity, concentration_alerts, total_value, target)
Parameters:
Return type:

None

class siege_utilities.analytics.PipelineAnalyzer[source]

Bases: object

Pipeline health metrics engine.

Parameters:
  • stages (list[str]) – Ordered stage names (first = entry, last = exit).

  • target (float | None) – Target pipeline value for coverage ratio calculation.

  • aging_threshold (float) – Multiplier for aging alerts (default 2.0 = alert at 2x average).

  • concentration_threshold (float) – Maximum single-item share before alert (default 0.40 = 40%).

Raises:

ValueError – If stages is empty or thresholds are invalid.

__init__(stages, target=None, aging_threshold=2.0, concentration_threshold=0.4)[source]
Parameters:
Return type:

None

analyze(items, *, as_of=None)[source]

Analyze pipeline health.

Parameters:
  • items (list[PipelineItem]) – Items currently in the pipeline.

  • as_of (datetime, optional) – Reference time for velocity calculation. Defaults to datetime.now().

Return type:

PipelineReport

Raises:

ValueError – If items is empty or contains unknown stages.

class siege_utilities.analytics.MappingRule[source]

Bases: object

A signal-to-action mapping rule.

Parameters:
  • signal (str) – The categorical input signal.

  • action (str) – The recommended action.

  • priority (int) – Lower number = higher priority. Used when multiple rules match.

signal: str
action: str
priority: int = 0
__init__(signal, action, priority=0)
Parameters:
Return type:

None

class siege_utilities.analytics.Outcome[source]

Bases: object

Recorded outcome for an intervention.

signal: str
action: str
success: bool
overridden: bool = False
override_reason: str | None = None
__init__(signal, action, success, overridden=False, override_reason=None)
Parameters:
  • signal (str)

  • action (str)

  • success (bool)

  • overridden (bool)

  • override_reason (str | None)

Return type:

None

class siege_utilities.analytics.EffectivenessReport[source]

Bases: object

Effectiveness statistics for one action.

action: str
total: int
successes: int
success_rate: float
__init__(action, total, successes, success_rate)
Parameters:
Return type:

None

class siege_utilities.analytics.InterventionMapper[source]

Bases: object

Rule-based intervention mapping engine.

Parameters:
  • rules (list[MappingRule]) – Signal-to-action mapping rules.

  • default_action (str | None) – Action for unmapped signals. If None, unmapped signals raise.

  • strict (bool) – If True, unmapped signals raise ValueError. If False, warn and return default_action.

Raises:

ValueError – If rules is empty or strict=False without default_action.

__init__(rules, default_action=None, strict=True)[source]
Parameters:
Return type:

None

property signals: list[str]
map(signal, *, override_action=None, override_reason=None)[source]

Map a signal to an action.

Parameters:
  • signal (str) – The categorical input signal.

  • override_action (str, optional) – Override the mapped action. Must include override_reason.

  • override_reason (str, optional) – Reason for the override (mandatory when overriding).

Returns:

The recommended action.

Return type:

str

Raises:

ValueError – If signal is unmapped and strict=True, or if override is given without a reason.

record_outcome(signal, action, success, *, overridden=False, override_reason=None)[source]

Record the outcome of an intervention.

Parameters:
  • signal (str) – The signal that triggered the intervention.

  • action (str) – The action taken.

  • success (bool) – Whether the intervention succeeded.

  • overridden (bool) – Whether the action was an override.

  • override_reason (str, optional) – Reason for override (required if overridden=True).

Raises:

ValueError – If overridden=True without override_reason.

Return type:

None

effectiveness()[source]

Compute effectiveness per action.

Returns:

One entry per distinct action, sorted by success rate ascending.

Return type:

list[EffectivenessReport]

Raises:

ValueError – If no outcomes have been recorded.

Submodules

Google Analytics Integration Module

This module provides comprehensive Google Analytics integration capabilities: - Connect to GA accounts via OAuth2 - Retrieve data from GA4 and Universal Analytics - Save data as Pandas or Spark dataframes - Associate GA accounts with client profiles - Batch data retrieval and processing

class siege_utilities.analytics.google_analytics.GoogleAnalyticsConnector[source]

Bases: object

Google Analytics connection and data retrieval manager.

__init__(client_id=None, client_secret=None, redirect_uri='urn:ietf:wg:oauth:2.0:oob', auth_method='oauth2', service_account_data=None)[source]

Initialize Google Analytics connector.

Parameters:
  • client_id (str) – OAuth2 client ID from Google Cloud Console (for OAuth2)

  • client_secret (str) – OAuth2 client secret from Google Cloud Console (for OAuth2)

  • redirect_uri (str) – OAuth2 redirect URI (for OAuth2)

  • auth_method (str) – Authentication method (“oauth2” or “service_account”)

  • service_account_data (Dict[str, Any]) – Service account credentials dict (for service account auth)

authenticate(token_file='ga_token.json')[source]

Authenticate with Google Analytics using OAuth2.

Parameters:

token_file (str) – Path to store/retrieve OAuth token

Raises:
  • google.auth.exceptions.* – On authentication failure.

  • OSError – If token file cannot be read/written.

Return type:

None

authenticate_service_account()[source]

Authenticate with Google Analytics using service account. Based on working implementation from GA project.

Raises:
  • ValueError – If no service account data is available.

  • google.auth.exceptions.* – On authentication failure.

  • OSError – If temp file operations fail.

Return type:

None

get_ga4_data(property_id, start_date, end_date, metrics, dimensions=None, row_limit=100000)[source]

Retrieve data from Google Analytics 4.

Parameters:
  • property_id (str) – GA4 property ID

  • start_date (str) – Start date as YYYY-MM-DD (also accepts the GA4 relative keywords today, yesterday, or NdaysAgo). Interpreted in the property’s configured timezone, not the caller’s local time — set this in the GA admin UI.

  • end_date (str) – End date, same format / TZ rules as start_date.

  • metrics (List[str]) – List of metrics to retrieve

  • dimensions (List[str]) – List of dimensions to retrieve

  • row_limit (int) – Maximum rows to retrieve

Returns:

Pandas DataFrame with GA4 data

Raises:

ValueError – If start_date / end_date is not a valid YYYY-MM-DD date or recognized GA4 relative keyword. Previously, malformed dates were forwarded raw to the GA API and returned an opaque 400 hours later in a batch run.

Return type:

pandas.DataFrame

get_ua_data(view_id, start_date, end_date, metrics, dimensions=None, max_results=100000)[source]

Retrieve data from Universal Analytics.

Parameters:
  • view_id (str) – UA view ID

  • start_date (str) – Start date (YYYY-MM-DD)

  • end_date (str) – End date (YYYY-MM-DD)

  • metrics (List[str]) – List of metrics to retrieve

  • dimensions (List[str]) – List of dimensions to retrieve

  • max_results (int) – Maximum results to retrieve

Returns:

Pandas DataFrame with UA data

Raises:

ValueError – If start_date / end_date is not a valid YYYY-MM-DD date or recognized GA relative keyword.

Return type:

pandas.DataFrame

save_as_pandas(df, output_path, format='parquet')[source]

Save DataFrame as Pandas format.

Parameters:
  • df (pandas.DataFrame) – Pandas DataFrame to save

  • output_path (str) – Output file path

  • format (str) – Output format (parquet, csv, excel, etc.)

Raises:
  • ValueError – If the format is unsupported.

  • OSError – If the file cannot be written.

Return type:

None

save_as_spark(df, output_path, spark_session=None)[source]

Save DataFrame as Spark DataFrame and optionally to storage.

Parameters:
  • df (pandas.DataFrame) – Pandas DataFrame to convert

  • output_path (str) – Output path for Spark DataFrame

  • spark_session (pyspark.sql.SparkSession | None) – Optional SparkSession (will create if not provided)

Raises:
  • ImportError – If PySpark is not available.

  • OSError – If the output path cannot be written.

Return type:

None

siege_utilities.analytics.google_analytics.batch_retrieve_ga_data(client_id, start_date, end_date, metrics, dimensions=None, output_format='pandas', output_directory='output/ga_data')[source]

Batch retrieve GA data for all accounts associated with a client.

Parameters:
  • client_id (str) – Client ID to retrieve data for

  • start_date (str) – Start date for data retrieval

  • end_date (str) – End date for data retrieval

  • metrics (List[str]) – List of metrics to retrieve

  • dimensions (List[str]) – List of dimensions to retrieve

  • output_format (str) – Output format (pandas, spark, or both)

  • output_directory (str) – Directory to save output files

Returns:

Dictionary with retrieval results

Return type:

Dict[str, Any]

siege_utilities.analytics.google_analytics.create_ga_account_profile(client_id, ga_property_id, account_type='ga4', credentials_file=None)[source]

Create a Google Analytics account profile linked to a client.

Parameters:
  • client_id (str) – Client ID from client management system

  • ga_property_id (str) – Google Analytics property ID

  • account_type (str) – Type of GA account (ga4, ua, or both)

  • credentials_file (str) – Path to OAuth credentials file

Returns:

GA account profile dictionary

Return type:

Dict[str, Any]

siege_utilities.analytics.google_analytics.create_ga_connector_from_1password(item_title='Google Analytics Service Account - Multi-Client Reporter')[source]

Create a GoogleAnalyticsConnector using service account from 1Password.

Deprecated since version The: auth mechanism (1Password) should not leak into an analytics API surface. Use the explicit two-step path instead:

from siege_utilities.config import get_google_service_account_from_1password
from siege_utilities.analytics import create_ga_connector_with_service_account

data = get_google_service_account_from_1password(item_title)
connector = create_ga_connector_with_service_account(data)

This function will be removed in v4.0.0. See docs/INTENT.md (D1) and ELE-2442 for the rationale.

Parameters:

item_title (str) – Title of the 1Password item containing service account

Returns:

GoogleAnalyticsConnector instance or None if failed

Return type:

GoogleAnalyticsConnector | None

siege_utilities.analytics.google_analytics.create_ga_connector_with_oauth2(client_id, client_secret, redirect_uri='urn:ietf:wg:oauth:2.0:oob')[source]

Create a GoogleAnalyticsConnector using OAuth2 authentication.

Parameters:
  • client_id (str) – OAuth2 client ID from Google Cloud Console

  • client_secret (str) – OAuth2 client secret from Google Cloud Console

  • redirect_uri (str) – OAuth2 redirect URI

Returns:

GoogleAnalyticsConnector instance configured for OAuth2 auth

Return type:

GoogleAnalyticsConnector

siege_utilities.analytics.google_analytics.create_ga_connector_with_service_account(service_account_data=None)[source]

Create a GoogleAnalyticsConnector using service account authentication.

Parameters:

service_account_data (Dict[str, Any]) – Service account credentials dict (optional, will try 1Password if None)

Returns:

GoogleAnalyticsConnector instance configured for service account auth

Return type:

GoogleAnalyticsConnector

siege_utilities.analytics.google_analytics.list_ga_accounts_for_client(client_id, config_directory='config')[source]

List all GA accounts associated with a client.

Parameters:
  • client_id (str) – Client ID to search for

  • config_directory (str) – Directory containing config files

Returns:

List of GA account profiles

Return type:

List[Dict[str, Any]]

siege_utilities.analytics.google_analytics.load_ga_account_profile(account_id, config_directory='config')[source]

Load GA account profile from JSON file.

Parameters:
  • account_id (str) – GA account ID to load

  • config_directory (str) – Directory containing config files

Returns:

GA account profile dictionary or None if not found

Return type:

Dict[str, Any] | None

siege_utilities.analytics.google_analytics.save_ga_account_profile(profile, config_directory='config')[source]

Save GA account profile to JSON file.

Parameters:
  • profile (Dict[str, Any]) – GA account profile dictionary

  • config_directory (str) – Directory to save config files

Returns:

Path to saved config file

Return type:

str

Google Docs write service.

Provides functions for creating documents, inserting text, tables, images, and performing batch updates via the Docs API v1.

Usage:

from siege_utilities.analytics.google_workspace import GoogleWorkspaceClient from siege_utilities.analytics.google_docs import (

create_document, insert_text, insert_table,

)

client = GoogleWorkspaceClient.from_service_account() doc_id = create_document(client, “Meeting Notes”) insert_text(client, doc_id, “Agendan”, bold=True) insert_table(client, doc_id, rows=3, cols=2)

siege_utilities.analytics.google_docs.batch_update(client, document_id, requests)[source]

Execute a batch of Docs API requests.

Delegates to GoogleWorkspaceClient.batch_update_document().

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • document_id (str) – Target document ID.

  • requests (List[Dict[str, Any]]) – List of request dicts per the Docs API batchUpdate spec.

Returns:

The API response dict.

Return type:

Dict[str, Any]

siege_utilities.analytics.google_docs.copy_document(client, document_id, title=None)[source]

Copy a document via the Drive API.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • document_id (str) – Source document ID.

  • title (str | None) – Title for the copy (default: “Copy of …”).

Returns:

The new document ID.

Return type:

str

siege_utilities.analytics.google_docs.create_document(client, title, folder_id=None)[source]

Create a new Google Doc and return its document ID.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • title (str) – Title for the new document.

  • folder_id (str | None) – Optional Drive folder ID to create the document in.

Returns:

The document ID string.

Return type:

str

siege_utilities.analytics.google_docs.get_document(client, document_id)[source]

Fetch full document metadata and content structure.

Returns:

The document resource dict.

Parameters:

document_id (str)

Return type:

Dict[str, Any]

siege_utilities.analytics.google_docs.insert_image(client, document_id, image_uri, index=1, width=None, height=None)[source]

Insert an image from a URL.

The URI must be publicly accessible or a Google Drive file.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • document_id (str) – Target document ID.

  • image_uri (str) – Public URL of the image.

  • index (int) – Character index for insertion.

  • width (float | None) – Optional width in points.

  • height (float | None) – Optional height in points.

Returns:

The API response dict.

Return type:

Dict[str, Any]

siege_utilities.analytics.google_docs.insert_paragraph(client, document_id, text, index=1, heading=None)[source]

Insert a paragraph with optional heading style.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • document_id (str) – Target document ID.

  • text (str) – Paragraph text (newline is appended automatically).

  • index (int) – Character index (1-based).

  • heading (str | None) – Named style ("HEADING_1" through "HEADING_6", "TITLE", "SUBTITLE", or None for normal text).

Returns:

The API response dict.

Return type:

Dict[str, Any]

siege_utilities.analytics.google_docs.insert_table(client, document_id, rows, cols, index=1)[source]

Insert an empty table at the given index.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • document_id (str) – Target document ID.

  • rows (int) – Number of rows.

  • cols (int) – Number of columns.

  • index (int) – Character index where the table is inserted.

Returns:

The API response dict.

Return type:

Dict[str, Any]

siege_utilities.analytics.google_docs.insert_text(client, document_id, text, index=1, bold=False, italic=False, font_size=None)[source]

Insert text at a given index in a document.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • document_id (str) – Target document ID.

  • text (str) – Text to insert.

  • index (int) – Character index (1-based; 1 = start of document body).

  • bold (bool) – Apply bold formatting.

  • italic (bool) – Apply italic formatting.

  • font_size (int | None) – Font size in points (None = default).

Returns:

The API response dict.

Return type:

Dict[str, Any]

siege_utilities.analytics.google_docs.read_document_text(client, document_id)[source]

Read the full plain-text content of a document.

Extracts text from all structural elements (paragraphs, tables, etc.).

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • document_id (str) – Target document ID.

Returns:

The document text as a single string.

Return type:

str

siege_utilities.analytics.google_docs.replace_text(client, document_id, find, replace_with, match_case=True)[source]

Find and replace text throughout a document.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • document_id (str) – Target document ID.

  • find (str) – Text to search for.

  • replace_with (str) – Replacement text.

  • match_case (bool) – Whether the search is case-sensitive.

Returns:

The API response dict.

Return type:

Dict[str, Any]

Google Sheets write service.

Provides functions for creating spreadsheets, writing data, managing tabs (sheets), and performing batch updates via the Sheets API v4.

All functions accept a GoogleWorkspaceClient for authentication.

Usage:

from siege_utilities.analytics.google_workspace import GoogleWorkspaceClient from siege_utilities.analytics.google_sheets import (

create_spreadsheet, write_dataframe, append_rows,

)

client = GoogleWorkspaceClient.from_service_account() spreadsheet_id = create_spreadsheet(client, “Q1 Report”) write_dataframe(client, spreadsheet_id, df)

siege_utilities.analytics.google_sheets.add_sheet(client, spreadsheet_id, title)[source]

Add a new tab/sheet to an existing spreadsheet.

Returns:

The new sheet ID (integer).

Parameters:
  • spreadsheet_id (str)

  • title (str)

Return type:

int

siege_utilities.analytics.google_sheets.append_rows(client, spreadsheet_id, range_, values, value_input_option='USER_ENTERED')[source]

Append rows after existing data in a range.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • spreadsheet_id (str) – Target spreadsheet ID.

  • range – A1 notation range to search for a table (e.g. "Sheet1").

  • values (List[List[Any]]) – Row-major list of lists to append.

  • value_input_option (str) – "RAW" or "USER_ENTERED" (default).

  • range_ (str)

Returns:

The API response dict.

Return type:

Dict[str, Any]

siege_utilities.analytics.google_sheets.batch_update(client, spreadsheet_id, requests)[source]

Execute a batch of Sheets API requests.

Delegates to GoogleWorkspaceClient.batch_update_spreadsheet().

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • spreadsheet_id (str) – Target spreadsheet ID.

  • requests (List[Dict[str, Any]]) – List of request dicts per the Sheets API batchUpdate spec.

Returns:

The API response dict.

Return type:

Dict[str, Any]

siege_utilities.analytics.google_sheets.copy_spreadsheet(client, spreadsheet_id, title=None)[source]

Copy an entire spreadsheet via the Drive API.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • spreadsheet_id (str) – Source spreadsheet ID.

  • title (str | None) – Title for the copy (default: “Copy of …”).

Returns:

The new spreadsheet ID.

Return type:

str

siege_utilities.analytics.google_sheets.create_spreadsheet(client, title, sheet_names=None, folder_id=None)[source]

Create a new Google Spreadsheet and return its ID.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • title (str) – Title for the new spreadsheet.

  • sheet_names (List[str] | None) – Optional list of sheet/tab names to create. If omitted, a single default “Sheet1” is created.

  • folder_id (str | None) – Optional Drive folder ID to create the spreadsheet in.

Returns:

The spreadsheet ID string.

Return type:

str

siege_utilities.analytics.google_sheets.get_spreadsheet_metadata(client, spreadsheet_id)[source]

Fetch spreadsheet metadata (title, sheets, locale, etc.).

Returns:

The spreadsheet resource dict.

Parameters:

spreadsheet_id (str)

Return type:

Dict[str, Any]

siege_utilities.analytics.google_sheets.read_dataframe(client, spreadsheet_id, range_='Sheet1', has_header=True)[source]

Read a range from a spreadsheet into a pandas DataFrame.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • spreadsheet_id (str) – Source spreadsheet ID.

  • range – A1 notation range (e.g. "Sheet1" or "Sheet1!A1:D100").

  • has_header (bool) – If True, first row is used as column names.

  • range_ (str)

Returns:

pandas DataFrame.

siege_utilities.analytics.google_sheets.read_values(client, spreadsheet_id, range_)[source]

Read values from a range.

Returns:

Row-major list of lists (may be ragged).

Parameters:
  • spreadsheet_id (str)

  • range_ (str)

Return type:

List[List[Any]]

siege_utilities.analytics.google_sheets.write_dataframe(client, spreadsheet_id, df, sheet_name='Sheet1', include_header=True, start_cell='A1')[source]

Write a pandas DataFrame to a sheet.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • spreadsheet_id (str) – Target spreadsheet ID.

  • df – pandas DataFrame to write.

  • sheet_name (str) – Tab name (default "Sheet1").

  • include_header (bool) – Whether to include column names as first row.

  • start_cell (str) – Top-left cell (default "A1").

Returns:

The API response dict.

Return type:

Dict[str, Any]

siege_utilities.analytics.google_sheets.write_values(client, spreadsheet_id, range_, values, value_input_option='USER_ENTERED')[source]

Write a 2-D list of values to a range.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • spreadsheet_id (str) – Target spreadsheet ID.

  • range – A1 notation range (e.g. "Sheet1!A1:D10").

  • values (List[List[Any]]) – Row-major list of lists.

  • value_input_option (str) – "RAW" or "USER_ENTERED" (default).

  • range_ (str)

Returns:

The API response dict.

Return type:

Dict[str, Any]

Google Slides write service.

Provides functions for creating presentations, adding slides, inserting text and images, and performing batch updates via the Slides API v1.

Usage:

from siege_utilities.analytics.google_workspace import GoogleWorkspaceClient from siege_utilities.analytics.google_slides import (

create_presentation, add_blank_slide, insert_text,

)

client = GoogleWorkspaceClient.from_service_account() pres_id = create_presentation(client, “Q1 Report”) slide_id = add_blank_slide(client, pres_id) insert_text(client, pres_id, slide_id, “Hello World”)

siege_utilities.analytics.google_slides.add_blank_slide(client, presentation_id, layout='BLANK', insertion_index=None)[source]

Add a blank slide to a presentation.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • presentation_id (str) – Target presentation ID.

  • layout (str) – Predefined layout ("BLANK", "TITLE", "TITLE_AND_BODY", etc.).

  • insertion_index (int | None) – Position (0-based). None appends at end.

Returns:

The new slide’s object ID.

Return type:

str

siege_utilities.analytics.google_slides.batch_update(client, presentation_id, requests)[source]

Execute a batch of Slides API requests.

Delegates to GoogleWorkspaceClient.batch_update_presentation().

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • presentation_id (str) – Target presentation ID.

  • requests (List[Dict[str, Any]]) – List of request dicts per the Slides API batchUpdate spec.

Returns:

The API response dict.

Return type:

Dict[str, Any]

siege_utilities.analytics.google_slides.copy_presentation(client, presentation_id, title=None)[source]

Copy an entire presentation via the Drive API.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • presentation_id (str) – Source presentation ID.

  • title (str | None) – Title for the copy (default: “Copy of …”).

Returns:

The new presentation ID.

Return type:

str

siege_utilities.analytics.google_slides.create_argument_slide(client, presentation_id, argument, slide_index=None)[source]

Add one slide for an Argument.

Layout is derived from argument.layout:

“full_width” → title / narrative / figure stacked vertically “side_by_side” → title top; narrative left, figure right

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • presentation_id (str) – Target presentation ID.

  • argument – Argument dataclass instance.

  • slide_index (int | None) – Insertion position. None → append at end.

Returns:

Slide object ID.

Return type:

str

siege_utilities.analytics.google_slides.create_presentation(client, title, folder_id=None)[source]

Create a new Google Slides presentation and return its ID.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • title (str) – Title for the new presentation.

  • folder_id (str | None) – Optional Drive folder ID to create the presentation in.

Returns:

The presentation ID string.

Return type:

str

siege_utilities.analytics.google_slides.create_report_from_arguments(client, title, arguments, folder_id=None, theme_presentation_id=None)[source]

Create a complete presentation from a list of Arguments.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • title (str) – Presentation title.

  • arguments (List) – List of Argument dataclass instances (one slide each).

  • folder_id (str | None) – Optional Drive folder to place the presentation in.

  • theme_presentation_id (str | None) – If given, copies this presentation first (preserves master slides / theme).

Returns:

Presentation ID of the newly created report.

Return type:

str

siege_utilities.analytics.google_slides.create_textbox(client, presentation_id, slide_id, text, left=100, top=100, width=400, height=50)[source]

Create a text box on a slide and populate it with text.

Dimensions are in EMU (English Metric Units). 1 inch = 914400 EMU. For convenience, this function accepts points (1 pt = 12700 EMU) but the values are treated as points internally.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • presentation_id (str) – Target presentation ID.

  • slide_id (str) – Slide object ID.

  • text (str) – Text to put in the box.

  • left (float) – Position in points from top-left.

  • top (float) – Position in points from top-left.

  • width (float) – Dimensions in points.

  • height (float) – Dimensions in points.

Returns:

The textbox object ID.

Return type:

str

siege_utilities.analytics.google_slides.get_presentation(client, presentation_id)[source]

Fetch full presentation metadata.

Returns:

The presentation resource dict.

Parameters:

presentation_id (str)

Return type:

Dict[str, Any]

siege_utilities.analytics.google_slides.insert_image(client, presentation_id, slide_id, image_url, left=100, top=100, width=400, height=300)[source]

Insert an image onto a slide from a URL.

The URL must be publicly accessible or a Google Drive file URL.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • presentation_id (str) – Target presentation ID.

  • slide_id (str) – Slide object ID.

  • image_url (str) – Public URL of the image.

  • left (float) – Position in points.

  • top (float) – Position in points.

  • width (float) – Size in points.

  • height (float) – Size in points.

Returns:

The image object ID.

Return type:

str

siege_utilities.analytics.google_slides.insert_text(client, presentation_id, object_id, text, insertion_index=0)[source]

Insert text into an existing shape or text box.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • presentation_id (str) – Target presentation ID.

  • object_id (str) – The shape/text-box object ID to insert into.

  • text (str) – Text string to insert.

  • insertion_index (int) – Character index within the shape’s text (default 0).

Returns:

The API response dict.

Return type:

Dict[str, Any]

siege_utilities.analytics.google_slides.upload_figure_to_drive(client, figure, filename, folder_id=None)[source]

Save a matplotlib Figure to a temp PNG, upload to Google Drive, return URL.

Parameters:
  • client – Authenticated GoogleWorkspaceClient.

  • figure – matplotlib Figure object.

  • filename (str) – Name for the uploaded file (without extension).

  • folder_id (str | None) – Optional Drive folder ID.

Returns:

Public URL string for the uploaded image (suitable for insert_image).

Return type:

str

Google Workspace base client for Docs, Sheets, and Slides write APIs.

Provides shared authentication and service-building logic reused by the Sheets, Slides, and Docs service modules.

Authentication follows the same patterns as GoogleAnalyticsConnector: - OAuth2 (interactive flow with token file) - Service Account (from 1Password or file) - Explicit Credentials object

Usage:

from siege_utilities.analytics.google_workspace import GoogleWorkspaceClient

# OAuth2 with token file client = GoogleWorkspaceClient.from_oauth(

client_id=”…”, client_secret=”…”, token_file=”token.json”,

)

# Service Account from 1Password client = GoogleWorkspaceClient.from_service_account()

# Get a specific API service sheets = client.sheets_service() docs = client.docs_service() slides = client.slides_service()

class siege_utilities.analytics.google_workspace.GoogleWorkspaceClient[source]

Bases: object

Authenticated client that builds Google API service objects.

Do not instantiate directly — use the from_oauth() or from_service_account() class methods.

__init__(credentials)[source]
classmethod from_oauth(client_id, client_secret, token_file=None, redirect_uri='urn:ietf:wg:oauth:2.0:oob', scopes=None)[source]

Authenticate via OAuth2 interactive flow.

If token_file exists and contains a valid/refreshable token, no browser interaction is needed.

Parameters:
Return type:

GoogleWorkspaceClient

classmethod from_1password(item_title='Google OAuth Client - siege_utilities', vault=None, account='TLTQ3ANAABGCNEK7KIAOTDNK2Q', token_file=None, scopes=None)[source]

Authenticate using credentials stored in a 1Password Document item.

Auto-detects whether the JSON document is an OAuth client secret (has "installed" or "web" key) or a service account key (has "type": "service_account"), and routes to the appropriate auth flow.

For OAuth: runs the installed-app flow (browser required on first use; cached token reused afterward).

For service account: authenticates server-to-server with no browser interaction.

Parameters:
  • item_title (str) – Title of the 1Password Document item.

  • vault (str | None) – 1Password vault name.

  • account (str | None) – 1Password account shorthand or UUID.

  • token_file (str | Path | None) – Path to cache the OAuth token (ignored for service accounts). Default: ~/.siege/tokens/workspace_token.json.

  • scopes (List[str] | None) – OAuth scopes (defaults to WORKSPACE_SCOPES).

Returns:

Authenticated GoogleWorkspaceClient.

Return type:

GoogleWorkspaceClient

classmethod from_service_account(service_account_data=None, service_account_file=None, scopes=None)[source]

Authenticate via service account credentials.

Provide service_account_data (dict) or service_account_file (path). If neither is given, attempts to fetch from 1Password via CredentialManager.get_google_service_account_from_1password().

Parameters:
Return type:

GoogleWorkspaceClient

classmethod from_credentials(credentials)[source]

Wrap an already-authenticated google.auth.credentials.Credentials.

Return type:

GoogleWorkspaceClient

classmethod from_account(account, person=None, scopes=None)[source]

Build a client from a GoogleAccount.

For OAuth accounts the method looks for a cached token_file first, then resolves oauth_integration_name from person to get client_id/client_secret for the OAuth flow.

For service accounts the method resolves service_account_ref via CredentialManager (1Password) or treats it as a file path.

Parameters:
Return type:

GoogleWorkspaceClient

classmethod from_registry(registry, google_account_id=None, person=None, scopes=None)[source]

Build a client from a registry’s default or specified account.

If google_account_id is given, looks it up directly; otherwise uses the registry’s default account.

Parameters:
Return type:

GoogleWorkspaceClient

sheets_service()[source]

Return the Google Sheets API v4 service object.

docs_service()[source]

Return the Google Docs API v1 service object.

slides_service()[source]

Return the Google Slides API v1 service object.

drive_service()[source]

Return the Google Drive API v3 service object.

property credentials
batch_update_spreadsheet(spreadsheet_id, requests)[source]

Execute a batch of Sheets API requests.

Parameters:
  • spreadsheet_id (str) – Target spreadsheet ID.

  • requests (List[Dict[str, Any]]) – List of request dicts per the Sheets API batchUpdate spec.

Returns:

The API response dict.

Return type:

Dict[str, Any]

batch_update_document(document_id, requests)[source]

Execute a batch of Docs API requests.

Parameters:
  • document_id (str) – Target document ID.

  • requests (List[Dict[str, Any]]) – List of request dicts per the Docs API batchUpdate spec.

Returns:

The API response dict.

Return type:

Dict[str, Any]

batch_update_presentation(presentation_id, requests)[source]

Execute a batch of Slides API requests.

Parameters:
  • presentation_id (str) – Target presentation ID.

  • requests (List[Dict[str, Any]]) – List of request dicts per the Slides API batchUpdate spec.

Returns:

The API response dict.

Return type:

Dict[str, Any]

static spreadsheet_url(spreadsheet_id)[source]

Return the live Google Sheets URL for a spreadsheet ID.

Parameters:

spreadsheet_id (str)

Return type:

str

static document_url(document_id)[source]

Return the live Google Docs URL for a document ID.

Parameters:

document_id (str)

Return type:

str

static presentation_url(presentation_id)[source]

Return the live Google Slides URL for a presentation ID.

Parameters:

presentation_id (str)

Return type:

str

static file_url(file_id, mime_type=None)[source]

Return the live Google Drive URL for a file ID.

If mime_type is provided, returns the appropriate editor URL. Otherwise returns the generic Drive file URL.

Parameters:
  • file_id (str)

  • mime_type (str | None)

Return type:

str

copy_file(file_id, title=None)[source]

Copy a Drive file (spreadsheet, doc, presentation) and return the new ID.

Parameters:
  • file_id (str) – The ID of the file to copy.

  • title (str | None) – Optional title for the copy. None keeps the default “Copy of …” naming.

Returns:

The new file’s ID.

Return type:

str

share_file(file_id, email, role='writer', send_notification=False)[source]

Share a Drive file with a user.

Parameters:
  • file_id (str) – The file to share.

  • email (str) – Email address of the recipient.

  • role (str) – "reader", "writer", or "commenter".

  • send_notification (bool) – Whether to send an email notification.

Returns:

The permission resource dict.

Return type:

Dict[str, Any]

move_to_folder(file_id, folder_id)[source]

Move a file into a Drive folder.

Parameters:
  • file_id (str) – The file to move.

  • folder_id (str) – Target folder ID.

Returns:

The updated file resource dict.

Return type:

Dict[str, Any]

Snowflake data warehouse connector for Siege Utilities.

Provides seamless integration with Snowflake for data warehousing and analytics.

class siege_utilities.analytics.snowflake_connector.SnowflakeConnector[source]

Bases: object

Snowflake data warehouse connector with advanced features.

__init__(account, user, password=None, warehouse=None, database=None, schema=None, role=None, config_file=None)[source]

Initialize Snowflake connector.

Parameters:
  • account (str) – Snowflake account identifier

  • user (str) – Snowflake username

  • password (str | None) – Snowflake password (optional if using config file)

  • warehouse (str | None) – Default warehouse to use

  • database (str | None) – Default database to use

  • schema (str | None) – Default schema to use

  • role (str | None) – Default role to use

  • config_file (str | Path | None) – Path to configuration file

connect()[source]

Establish connection to Snowflake.

Raises:

ConnectionError – If the connection attempt fails.

Return type:

None

disconnect()[source]

Close Snowflake connection.

Return type:

None

execute_query(query, params=None)[source]

Execute a SQL query.

Parameters:
  • query (str) – SQL query string

  • params (Dict[str, Any] | None) – Query parameters (optional)

Returns:

Query results as list of tuples

Raises:
Return type:

List[tuple]

execute_ddl(ddl_statement)[source]

Execute DDL statements (CREATE, ALTER, DROP, etc.).

Parameters:

ddl_statement (str) – DDL SQL statement

Raises:
Return type:

None

upload_dataframe(df, table_name, database=None, schema=None, auto_create_table=True, overwrite=False)[source]

Upload pandas DataFrame to Snowflake table.

Parameters:
  • df (pd.DataFrame) – Pandas DataFrame to upload

  • table_name (str) – Target table name

  • database (str | None) – Target database (uses default if not specified)

  • schema (str | None) – Target schema (uses default if not specified)

  • auto_create_table (bool) – Whether to automatically create table if it doesn’t exist

  • overwrite (bool) – Whether to overwrite existing table

Raises:
Return type:

None

download_dataframe(query, params=None)[source]

Download data from Snowflake as pandas DataFrame.

Parameters:
  • query (str) – SQL query to execute

  • params (Dict[str, Any] | None) – Query parameters (optional)

Returns:

Pandas DataFrame with query results

Raises:
Return type:

pd.DataFrame

get_table_info(table_name, database=None, schema=None)[source]

Get information about a Snowflake table.

Parameters:
  • table_name (str) – Name of the table

  • database (str | None) – Database name (uses default if not specified)

  • schema (str | None) – Schema name (uses default if not specified)

Returns:

Dictionary with table information

Raises:
Return type:

Dict[str, Any]

list_tables(database=None, schema=None)[source]

List all tables in a database/schema.

Parameters:
  • database (str | None) – Database name (uses default if not specified)

  • schema (str | None) – Schema name (uses default if not specified)

Returns:

List of table names

Raises:
Return type:

List[str]

siege_utilities.analytics.snowflake_connector.get_snowflake_connector(config_file=None)[source]

Get Snowflake connector instance from configuration.

Parameters:

config_file (str | Path | None)

Return type:

SnowflakeConnector

siege_utilities.analytics.snowflake_connector.upload_to_snowflake(df, table_name, config_file=None, **kwargs)[source]

Convenience function to upload DataFrame to Snowflake.

Parameters:
  • df (pd.DataFrame) – Pandas DataFrame to upload.

  • table_name (str) – Target table name.

  • config_file (str | Path | None) – Path to configuration file (optional).

  • **kwargs – Forwarded to SnowflakeConnector.upload_dataframe(). See that method for accepted parameters.

Return type:

None

siege_utilities.analytics.snowflake_connector.download_from_snowflake(query, config_file=None, **kwargs)[source]

Convenience function to download DataFrame from Snowflake.

Parameters:
  • query (str) – SQL query to execute.

  • config_file (str | Path | None) – Path to configuration file (optional).

  • **kwargs – Forwarded to SnowflakeConnector.download_dataframe(). See that method for accepted parameters.

Return type:

pd.DataFrame

siege_utilities.analytics.snowflake_connector.execute_snowflake_query(query, config_file=None, **kwargs)[source]

Convenience function to execute Snowflake query.

Parameters:
  • query (str) – SQL query string.

  • config_file (str | Path | None) – Path to configuration file (optional).

  • **kwargs – Forwarded to SnowflakeConnector.execute_query(). See that method for accepted parameters.

Return type:

List[tuple]

Data.world connector for Siege Utilities.

Provides seamless integration with data.world for data discovery, access, and collaboration.

class siege_utilities.analytics.datadotworld_connector.DataDotWorldConnector[source]

Bases: object

Data.world connector with advanced data discovery and access features.

__init__(api_token=None, config_file=None)[source]

Initialize Data.world connector.

Parameters:
  • api_token (str | None) – Data.world API token (optional if using config file)

  • config_file (str | Path | None) – Path to configuration file

search_datasets(query, limit=50, owner=None, tags=None)[source]

Search for datasets on data.world.

Parameters:
  • query (str) – Search query string

  • limit (int) – Maximum number of results to return

  • owner (str | None) – Filter by dataset owner

  • tags (List[str] | None) – Filter by tags

Returns:

List of dataset information dictionaries

Raises:

ConnectionError – If the API request fails.

Return type:

List[Dict[str, Any]]

get_dataset_info(dataset_id)[source]

Get detailed information about a specific dataset.

Parameters:

dataset_id (str) – Dataset identifier (format: owner/dataset)

Returns:

Dictionary with detailed dataset information

Raises:

ConnectionError – If the API request fails.

Return type:

Dict[str, Any]

list_dataset_files(dataset_id)[source]

List all files in a dataset.

Parameters:

dataset_id (str) – Dataset identifier (format: owner/dataset)

Returns:

List of file information dictionaries

Raises:

ConnectionError – If the API request fails.

Return type:

List[Dict[str, Any]]

download_file(dataset_id, file_name, output_path=None)[source]

Download a specific file from a dataset.

Parameters:
  • dataset_id (str) – Dataset identifier (format: owner/dataset)

  • file_name (str) – Name of the file to download

  • output_path (str | Path | None) – Local path to save the file (optional)

Returns:

Path to the downloaded file

Raises:
Return type:

Path

load_dataset_as_dataframe(dataset_id, file_name=None)[source]

Load a dataset file directly as a pandas DataFrame.

Parameters:
  • dataset_id (str) – Dataset identifier (format: owner/dataset)

  • file_name (str | None) – Name of the file to load (optional, loads first file if not specified)

Returns:

Pandas DataFrame with the data

Raises:
Return type:

pd.DataFrame

query_dataset(dataset_id, query, query_type='sql')[source]

Execute a query against a dataset.

Parameters:
  • dataset_id (str) – Dataset identifier (format: owner/dataset)

  • query (str) – Query string (SQL or SPARQL)

  • query_type (str) – Type of query (‘sql’ or ‘sparql’)

Returns:

Pandas DataFrame with query results

Raises:
Return type:

pd.DataFrame

get_dataset_schema(dataset_id)[source]

Get the schema information for a dataset.

Parameters:

dataset_id (str) – Dataset identifier (format: owner/dataset)

Returns:

Dictionary with schema information

Raises:

ConnectionError – If the API request fails.

Return type:

Dict[str, Any]

create_dataset(owner, dataset_id, title, description, tags=None, license='Public Domain', visibility='OPEN')[source]

Create a new dataset on data.world.

Parameters:
  • owner (str) – Dataset owner username

  • dataset_id (str) – Unique dataset identifier

  • title (str) – Dataset title

  • description (str) – Dataset description

  • tags (List[str] | None) – List of tags (optional)

  • license (str) – Dataset license (optional)

  • visibility (str) – Dataset visibility (‘OPEN’ or ‘PRIVATE’)

Returns:

owner/dataset_id)

Return type:

Created dataset ID (format

Raises:
upload_file(dataset_id, file_path, file_name=None)[source]

Upload a file to an existing dataset.

Parameters:
  • dataset_id (str) – Dataset identifier (format: owner/dataset)

  • file_path (str | Path) – Local path to the file to upload

  • file_name (str | None) – Name to use for the file on data.world (optional)

Raises:
Return type:

None

update_dataset(dataset_id, title=None, description=None, tags=None, license=None)[source]

Update an existing dataset.

Parameters:
  • dataset_id (str) – Dataset identifier (format: owner/dataset)

  • title (str | None) – New title (optional)

  • description (str | None) – New description (optional)

  • tags (List[str] | None) – New tags (optional)

  • license (str | None) – New license (optional)

Raises:
Return type:

None

delete_dataset(dataset_id)[source]

Delete a dataset.

Parameters:

dataset_id (str) – Dataset identifier (format: owner/dataset)

Raises:
Return type:

None

siege_utilities.analytics.datadotworld_connector.get_datadotworld_connector(config_file=None)[source]

Get Data.world connector instance from configuration.

Parameters:

config_file (str | Path | None)

Return type:

DataDotWorldConnector

siege_utilities.analytics.datadotworld_connector.list_datasets(limit=50, config_file=None, **kwargs)[source]

Standalone function to list available datasets.

Parameters:
  • limit (int) – Maximum number of results to return

  • config_file (str | Path | None) – Optional configuration file path

  • **kwargs – Additional arguments to pass to search_datasets

Returns:

List of dataset information dictionaries

Return type:

List[Dict[str, Any]]

siege_utilities.analytics.datadotworld_connector.search_datasets(query, config_file=None, **kwargs)[source]

Standalone function to search for datasets.

Parameters:
  • query (str) – Search query string

  • config_file (str | Path | None) – Path to configuration file (optional)

  • **kwargs – Additional search parameters

Returns:

List of matching datasets

Return type:

List[Dict[str, Any]]

siege_utilities.analytics.datadotworld_connector.search_datadotworld_datasets(query, config_file=None, **kwargs)[source]

Convenience function to search for datasets.

Parameters:
  • query (str) – Search query string.

  • config_file (str | Path | None) – Path to configuration file (optional).

  • **kwargs – Forwarded to DataDotWorldConnector.search_datasets(). See that method for accepted parameters.

Return type:

List[Dict[str, Any]]

siege_utilities.analytics.datadotworld_connector.load_datadotworld_dataset(dataset_id, config_file=None, **kwargs)[source]

Convenience function to load a dataset as DataFrame.

Parameters:
  • dataset_id (str) – Dataset identifier (format: owner/dataset).

  • config_file (str | Path | None) – Path to configuration file (optional).

  • **kwargs – Forwarded to DataDotWorldConnector.load_dataset_as_dataframe(). See that method for accepted parameters.

Return type:

pd.DataFrame

siege_utilities.analytics.datadotworld_connector.query_datadotworld_dataset(dataset_id, query, config_file=None, **kwargs)[source]

Convenience function to query a dataset.

Parameters:
  • dataset_id (str) – Dataset identifier (format: owner/dataset).

  • query (str) – Query string (SQL or SPARQL).

  • config_file (str | Path | None) – Path to configuration file (optional).

  • **kwargs – Forwarded to DataDotWorldConnector.query_dataset(). See that method for accepted parameters.

Return type:

pd.DataFrame

Facebook Business Integration Module

This module provides comprehensive Facebook Business integration capabilities: - Connect to Facebook Business accounts via OAuth2 - Retrieve data from Facebook Ads, Pages, and Business Manager - Save data as Pandas or Spark dataframes - Associate Facebook accounts with client profiles - Batch data retrieval and processing

class siege_utilities.analytics.facebook_business.FacebookBusinessConnector[source]

Bases: object

Facebook Business connection and data retrieval manager.

__init__(access_token, app_id=None, app_secret=None)[source]

Initialize Facebook Business connector.

Parameters:
  • access_token (str) – Facebook access token

  • app_id (str) – Facebook app ID (optional)

  • app_secret (str) – Facebook app secret (optional)

get_ad_accounts()[source]

Get list of accessible ad accounts.

Returns:

List of ad account information

Return type:

List[Dict[str, Any]]

get_ad_insights(ad_account_id, start_date, end_date, fields=None, breakdowns=None)[source]

Retrieve ad insights from Facebook Ads.

Parameters:
  • ad_account_id (str) – Facebook ad account ID

  • start_date (str) – Start date (YYYY-MM-DD)

  • end_date (str) – End date (YYYY-MM-DD)

  • fields (List[str]) – List of insight fields to retrieve

  • breakdowns (List[str]) – List of breakdowns to apply

Returns:

Pandas DataFrame with ad insights

Return type:

pandas.DataFrame

get_page_insights(page_id, start_date, end_date, metrics=None)[source]

Retrieve page insights from Facebook Pages.

Parameters:
  • page_id (str) – Facebook page ID

  • start_date (str) – Start date (YYYY-MM-DD)

  • end_date (str) – End date (YYYY-MM-DD)

  • metrics (List[str]) – List of metrics to retrieve

Returns:

Pandas DataFrame with page insights

Return type:

pandas.DataFrame

get_business_insights(business_id, start_date, end_date, metrics=None)[source]

Retrieve business insights from Facebook Business Manager.

Parameters:
  • business_id (str) – Facebook business ID

  • start_date (str) – Start date (YYYY-MM-DD)

  • end_date (str) – End date (YYYY-MM-DD)

  • metrics (List[str]) – List of metrics to retrieve

Returns:

Pandas DataFrame with business insights

Return type:

pandas.DataFrame

save_as_pandas(df, output_path, format='parquet')[source]

Save DataFrame as Pandas format.

Parameters:
  • df (pandas.DataFrame) – Pandas DataFrame to save

  • output_path (str) – Output file path

  • format (str) – Output format (parquet, csv, excel, etc.)

Raises:
  • ValueError – If the format is unsupported.

  • OSError – If the file cannot be written.

Return type:

None

save_as_spark(df, output_path, spark_session=None)[source]

Save DataFrame as Spark DataFrame and optionally to storage.

Parameters:
  • df (pandas.DataFrame) – Pandas DataFrame to convert

  • output_path (str) – Output path for Spark DataFrame

  • spark_session (pyspark.sql.SparkSession | None) – Optional SparkSession (will create if not provided)

Raises:
  • ImportError – If PySpark is not available.

  • OSError – If the output path cannot be written.

Return type:

None

siege_utilities.analytics.facebook_business.batch_retrieve_facebook_data(client_id, start_date, end_date, data_types=None, output_format='pandas', output_directory='output/facebook_data')[source]

Batch retrieve Facebook data for all accounts associated with a client.

Parameters:
  • client_id (str) – Client ID to retrieve data for

  • start_date (str) – Start date for data retrieval

  • end_date (str) – End date for data retrieval

  • data_types (List[str]) – Types of data to retrieve (ads, pages, business)

  • output_format (str) – Output format (pandas, spark, or both)

  • output_directory (str) – Directory to save output files

Returns:

Dictionary with retrieval results

Return type:

Dict[str, Any]

siege_utilities.analytics.facebook_business.create_facebook_account_profile(client_id, fb_account_id, account_type='ad_account', access_token=None)[source]

Create a Facebook account profile linked to a client.

Parameters:
  • client_id (str) – Client ID from client management system

  • fb_account_id (str) – Facebook account ID

  • account_type (str) – Type of FB account (ad_account, page, business)

  • access_token (str) – Facebook access token

Returns:

Facebook account profile dictionary

Return type:

Dict[str, Any]

siege_utilities.analytics.facebook_business.list_facebook_accounts_for_client(client_id, config_directory='config')[source]

List all Facebook accounts associated with a client.

Parameters:
  • client_id (str) – Client ID to search for

  • config_directory (str) – Directory containing config files

Returns:

List of Facebook account profiles

Return type:

List[Dict[str, Any]]

siege_utilities.analytics.facebook_business.load_facebook_account_profile(account_id, config_directory='config')[source]

Load Facebook account profile from JSON file.

Parameters:
  • account_id (str) – Facebook account ID to load

  • config_directory (str) – Directory containing config files

Returns:

Facebook account profile dictionary or None if not found

Return type:

Dict[str, Any] | None

siege_utilities.analytics.facebook_business.save_facebook_account_profile(profile, config_directory='config')[source]

Save Facebook account profile to JSON file.

Parameters:
  • profile (Dict[str, Any]) – Facebook account profile dictionary

  • config_directory (str) – Directory to save config files

Returns:

Path to saved config file

Return type:

str

Vista Social analytics connector.

Vista Social (https://vistasocial.com) is a social-media management platform that aggregates engagement, posts, and audience metrics across Facebook, Instagram, LinkedIn, X, TikTok, YouTube, and other channels. This module provides a thin connector that auths against the Vista Social REST API and exposes a few common reporting calls in the same shape as the other connectors in this package (FacebookBusinessConnector, DataDotWorldConnector).

Why “thin”

Vista Social’s REST API documentation requires an authenticated account; the public website does not enumerate endpoint URLs. This connector ships with:

  • The base _request helper that handles auth headers, retries, and error normalization – fully tested.

  • Concrete account, profiles, posts, analytics methods that wrap likely endpoint paths (/v1/accounts, /v1/profiles, /v1/posts, /v1/analytics). These are informed by the publicly visible URL structure on the Vista Social web app and are documented as “best-known” rather than spec-confirmed.

When you obtain real Vista Social API documentation (request access at api@vistasocial.com), verify the endpoints against the docs and adjust this module. The _request plumbing is correct regardless of which endpoints exist.

The intended consumer is siege_utilities.reporting, which will embed the returned analytics into a combined GA4 + social-media PDF report (the second half of #306). That work lives in a follow-up PR.

exception siege_utilities.analytics.vista_social.VistaSocialError[source]

Bases: RuntimeError

Base class for all Vista Social connector failures.

exception siege_utilities.analytics.vista_social.VistaSocialAuthError[source]

Bases: VistaSocialError

Authentication failed (401/403). Token is missing, wrong, or expired.

exception siege_utilities.analytics.vista_social.VistaSocialRateLimitError[source]

Bases: VistaSocialError

API rate limit hit (429). Caller can back off and retry later.

class siege_utilities.analytics.vista_social.VistaSocialResponse[source]

Bases: object

Structured response from a Vista Social API call.

The connector returns this rather than the raw requests.Response so consumers don’t need to know about the underlying HTTP library.

status_code

HTTP status code (200 / 201 etc.).

Type:

int

data

Parsed JSON body. Empty dict if the response had no body (e.g. 204 No Content) or wasn’t JSON-decodable.

Type:

Mapping[str, Any]

headers

Response headers – useful for inspecting rate-limit counters (X-RateLimit-Remaining, Retry-After).

Type:

Mapping[str, str]

url

The fully-qualified URL that was called, for logging.

Type:

str

status_code: int
data: Mapping[str, Any]
headers: Mapping[str, str]
url: str = ''
__init__(status_code, data, headers=<factory>, url='')
Parameters:
Return type:

None

class siege_utilities.analytics.vista_social.VistaSocialConnector[source]

Bases: object

Bearer-token authenticated client for the Vista Social REST API.

Usage:

from siege_utilities.analytics.vista_social import VistaSocialConnector

client = VistaSocialConnector(api_token=os.environ["VISTA_SOCIAL_TOKEN"])
accounts = client.list_accounts()
analytics = client.get_account_analytics(
    account_id=accounts[0]["id"],
    start_date="2026-01-01",
    end_date="2026-01-31",
)

All methods raise:

The connector follows the project’s failure-mode discipline (see docs/FAILURE_MODES.md): no method silently returns an empty dict on failure. Every failure mode is either a typed exception or a None return with a documented meaning.

__init__(api_token, *, base_url='https://api.vistasocial.com', timeout=30, retry_attempts=3, retry_backoff=1.5)[source]
Parameters:
Return type:

None

close()[source]

Close the underlying HTTP session.

Return type:

None

list_accounts()[source]

Return the list of accounts this token can access.

Wraps GET /v1/accounts. Returns the decoded data list from the response, or an empty list if the API returned nothing. Raises on auth / rate-limit / network failures (no silent empty-on-error).

Return type:

List[Mapping[str, Any]]

list_profiles(account_id)[source]

Return social profiles connected to account_id.

Wraps GET /v1/accounts/{account_id}/profiles.

Parameters:

account_id (str)

Return type:

List[Mapping[str, Any]]

get_account_analytics(account_id, *, start_date, end_date, metrics=None)[source]

Fetch aggregate analytics for account_id over a date range.

Parameters:
  • account_id (str) – Vista Social account id (string, opaque).

  • start_date (str) – ISO-8601 date (YYYY-MM-DD), inclusive.

  • end_date (str) – ISO-8601 date, inclusive.

  • metrics (List[str] | None) – Optional list of metric names (e.g. ["impressions", "engagements", "reach", "follower_count"]). If omitted, Vista Social returns its default metric set.

Return type:

Dict[str, Any]

Wraps GET /v1/accounts/{account_id}/analytics. Returns the decoded JSON body verbatim – Vista Social returns a structured document with metric breakdowns; consumers can extract what they need.

list_posts(account_id, *, start_date=None, end_date=None, limit=100)[source]

Return posts for account_id with optional date filtering.

Wraps GET /v1/accounts/{account_id}/posts. Pagination is intentionally simple here – consumers that need full enumeration should call repeatedly with adjusted date ranges or extend this connector with cursor handling once the real API spec is known.

Parameters:
  • account_id (str)

  • start_date (str | None)

  • end_date (str | None)

  • limit (int)

Return type:

List[Mapping[str, Any]]