Module: Cdss::Utils

Overview

Provides utility methods for handling dates, query parameters, and API pagination.

This module contains helper methods used across the CDSS API client for data formatting, safe type conversion, and managing paginated responses.

Instance Method Summary collapse

Instance Method Details

#batch_dates(start_date, end_date) ⇒ Array<Array<Date>>

Splits a date range into yearly chunks.

Examples:

Split a multi-year range

batch_dates(Date.new(2020,1,1), Date.new(2022,6,30))
#=> [[2020-01-01, 2020-12-31], [2021-01-01, 2021-12-31], [2022-01-01, 2022-06-30]]

Parameters:

  • start_date (Date, nil)

    Beginning of the date range

  • end_date (Date, nil)

    End of the date range

Returns:

  • (Array<Array<Date>>)

    Array of date pairs representing yearly chunks



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/cdss/utils.rb', line 17

def batch_dates(start_date, end_date)
  start_date ||= Date.new(1900, 1, 1)
  end_date ||= Date.today
  start_year = start_date.year
  end_year = end_date.year
  if start_year == end_year
    [[start_date, end_date]]
  else
    dates = []
    # First year
    dates << [start_date, Date.new(start_year, 12, 31)]
    # Middle years
    ((start_year + 1)...end_year).each do |year|
      dates << [Date.new(year, 1, 1), Date.new(year, 12, 31)]
    end
    # Last year
    dates << [Date.new(end_year, 1, 1), end_date]
    dates
  end
end

#build_query(params = {}, encode: false) ⇒ Hash

Builds a query hash for API requests.

Examples:

Build a simple query

build_query({ name: "test", id: 123 })
#=> { format: "json", name: "test", id: "123" }

Parameters:

  • params (Hash) (defaults to: {})

    Query parameters to include

  • encode (Boolean) (defaults to: false)

    Whether to URL encode parameter values

Returns:

  • (Hash)

    Query hash with formatted parameters



59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/cdss/utils.rb', line 59

def build_query(params = {}, encode: false)
  base_query = {
    format: "json"
  }
  params.each do |key, value|
    formatted_value = format_query_param(value)
    if formatted_value
      base_query[key] = encode ? URI.encode_www_form_component(formatted_value) : formatted_value
    end
  end
  base_query
end

#fetch_paginated_data(endpoint:, query:) {|Hash| ... } ⇒ Array

Fetches all pages of data from a paginated API endpoint.

Examples:

Fetch paginated data

fetch_paginated_data(endpoint: "/api/data", query: { type: "test" }) do |data|
  process_data(data)
end

Parameters:

  • endpoint (String)

    API endpoint path

  • query (Hash)

    Query parameters for the request

Yields:

  • (Hash)

    Block to process each page of response data

Yield Returns:

  • (Array)

    Processed records from the response

Returns:

  • (Array)

    Combined results from all pages



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/cdss/utils.rb', line 133

def fetch_paginated_data(endpoint:, query:)
  page_size = 50_000
  page_index = 1
  results = []
  loop do
    query = query.merge(pageSize: page_size, pageIndex: page_index)
    response = get(endpoint, query: query)
    data = handle_response(response)
    records = yield(data)
    break if records.empty?

    results.concat(records)
    break if records.size < page_size

    page_index += 1
  end
  results
end

#format_date(date, special_format: false) ⇒ String?

Formats a date for API requests.

Examples:

Format a date

format_date(Date.new(2023,1,1)) #=> "01-01-2023"

Parameters:

  • date (Date)

    The date to format

  • special_format (Boolean) (defaults to: false)

    Whether to use forward slashes instead of hyphens

Returns:

  • (String, nil)

    Formatted date string or nil if input is nil



79
80
81
82
83
84
# File 'lib/cdss/utils.rb', line 79

def format_date(date, special_format: false)
  return nil unless date

  date = date.strftime("%m-%d-%Y")
  special_format ? date.gsub("-", "%2F") : date
end

#format_query_param(value) ⇒ String?

Formats a query parameter value for API requests.

Examples:

Format an array parameter

format_query_param(['a', 'b']) #=> "a,b"

Parameters:

  • value (Object)

    The value to format

Returns:

  • (String, nil)

    Formatted value or nil if input is nil



44
45
46
47
48
49
# File 'lib/cdss/utils.rb', line 44

def format_query_param(value)
  return nil if value.nil?
  return value.join(",") if value.is_a?(Array)

  value.to_s
end

#parse_timestamp(datetime_str) ⇒ DateTime?

Safely parses a timestamp string.

Examples:

Parse a timestamp

parse_timestamp("2023-01-01 12:00:00")

Parameters:

  • datetime_str (String)

    Timestamp string to parse

Returns:

  • (DateTime, nil)

    Parsed DateTime object or nil if parsing fails



92
93
94
95
96
# File 'lib/cdss/utils.rb', line 92

def parse_timestamp(datetime_str)
  DateTime.parse(datetime_str) if datetime_str
rescue ArgumentError
  nil
end

#safe_float(value) ⇒ Float?

Safely converts a value to a float.

Examples:

Convert a string to float

safe_float("123.45") #=> 123.45

Parameters:

  • value (Object)

    Value to convert

Returns:

  • (Float, nil)

    Converted float or nil if conversion fails



104
105
106
107
108
# File 'lib/cdss/utils.rb', line 104

def safe_float(value)
  Float(value)
rescue TypeError, ArgumentError
  nil
end

#safe_integer(value) ⇒ Integer?

Safely converts a value to an integer.

Examples:

Convert a string to integer

safe_integer("123") #=> 123

Parameters:

  • value (Object)

    Value to convert

Returns:

  • (Integer, nil)

    Converted integer or nil if conversion fails



116
117
118
119
120
# File 'lib/cdss/utils.rb', line 116

def safe_integer(value)
  Integer(value)
rescue TypeError, ArgumentError
  nil
end