Class: AnalyticsOps::Workspace
- Inherits:
-
Object
- Object
- AnalyticsOps::Workspace
- Defined in:
- lib/analytics_ops/workspace.rb,
sig/analytics_ops.rbs
Overview
Primary Ruby API. Loading a workspace validates local data but performs no network calls.
Defined Under Namespace
Classes: DoctorResult, Verification
Constant Summary collapse
- MAX_EXPORT_ROWS =
1_000_000- DEFAULT_PAGE_SIZE =
100_000
Instance Attribute Summary collapse
-
#desired_state ⇒ DesiredState
readonly
Returns the value of attribute desired_state.
Class Method Summary collapse
Instance Method Summary collapse
- #access_report(date_ranges: nil, limit: 1_000) ⇒ Object
- #apply(plan_or_path, confirm: false) ⇒ Applier::Result
- #audit ⇒ Plan
- #change_history(limit: 100, days: 30) ⇒ Governance::ChangeHistory
- #discover ⇒ Array[Resources::Account]
- #doctor ⇒ DoctorResult
- #each_report_page(name_or_definition, date_ranges: nil, page_size: DEFAULT_PAGE_SIZE, max_rows: MAX_EXPORT_ROWS) ⇒ Object
- #export_report(name_or_definition, path:, date_ranges: nil, page_size: DEFAULT_PAGE_SIZE, max_rows: MAX_EXPORT_ROWS) ⇒ Object
- #funnel(name, date_ranges: nil) ⇒ BigQuery::Result
- #governance ⇒ Governance::Result
- #health(date_ranges: nil) ⇒ Health::Result
-
#initialize(desired_state:, admin: nil, data: nil, bigquery: nil, service_account: nil, transport: :grpc, timeout: nil, logger: nil) ⇒ Workspace
constructor
A new instance of Workspace.
- #overview(date_ranges: nil) ⇒ Reports::OverviewResult
- #plan ⇒ Plan
- #raw_report(name, date_ranges: nil, limit: 1_000) ⇒ Object
- #realtime(name_or_definition = "realtime_events") ⇒ Reports::Result
- #report(name_or_definition, date_ranges: nil) ⇒ Object
- #report_compatibility(name_or_definition) ⇒ Object
- #report_metadata(query: nil, kind: nil) ⇒ Reports::FieldList
- #report_recipes ⇒ Reports::RecipeList
- #snapshot ⇒ Snapshot
- #verify ⇒ Verification
Constructor Details
#initialize(desired_state:, admin: nil, data: nil, bigquery: nil, service_account: nil, transport: :grpc, timeout: nil, logger: nil) ⇒ Workspace
Returns a new instance of Workspace.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/analytics_ops/workspace.rb', line 62 def initialize(desired_state:, admin: nil, data: nil, bigquery: nil, service_account: nil, transport: :grpc, timeout: nil, logger: nil) unless service_account.nil? || service_account.is_a?(ServiceAccount) raise ConfigurationError, "service_account must be an AnalyticsOps::ServiceAccount" end @desired_state = desired_state @admin = admin @injected_admin = admin @data = data @bigquery = bigquery @service_account = service_account @transport = transport @timeout = timeout @logger = logger end |
Instance Attribute Details
#desired_state ⇒ DesiredState (readonly)
Returns the value of attribute desired_state.
45 46 47 |
# File 'lib/analytics_ops/workspace.rb', line 45 def desired_state @desired_state end |
Class Method Details
.load(path, profile:, environment: ENV, admin: nil, data: nil, bigquery: nil, service_account: nil, transport: :grpc, timeout: nil, logger: nil) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/analytics_ops/workspace.rb', line 47 def self.load(path, profile:, environment: ENV, admin: nil, data: nil, bigquery: nil, service_account: nil, transport: :grpc, timeout: nil, logger: nil) document = Configuration.load(path, environment:) new( desired_state: document.profile(profile), admin:, data:, bigquery:, service_account:, transport:, timeout:, logger: ) end |
Instance Method Details
#access_report(date_ranges: nil, limit: 1_000) ⇒ Object
215 216 217 218 |
# File 'lib/analytics_ops/workspace.rb', line 215 def access_report(date_ranges: nil, limit: 1_000) ranges = date_ranges || Reports::Period.resolve(last_days: Reports::Period::DEFAULT_DAYS, compare: false) admin.access_report(desired_state.property_id, date_ranges: ranges, limit:) end |
#apply(plan_or_path, confirm: false) ⇒ Applier::Result
95 96 97 98 99 |
# File 'lib/analytics_ops/workspace.rb', line 95 def apply(plan_or_path, confirm: false) saved_plan = plan_or_path.is_a?(Plan) ? plan_or_path : Plan.load(plan_or_path) validate_plan_target!(saved_plan) Applier.new(admin: edit_admin).call(saved_plan, confirm:) end |
#change_history(limit: 100, days: 30) ⇒ Governance::ChangeHistory
211 212 213 |
# File 'lib/analytics_ops/workspace.rb', line 211 def change_history(limit: 100, days: 30) edit_admin.change_history(desired_state.property_id, limit:, days:) end |
#discover ⇒ Array[Resources::Account]
79 80 81 |
# File 'lib/analytics_ops/workspace.rb', line 79 def discover admin.discover end |
#doctor ⇒ DoctorResult
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/analytics_ops/workspace.rb', line 249 def doctor remote = snapshot checks = [ { "name" => "configuration", "status" => "ok", "detail" => "Profile #{desired_state.profile} is valid" }, { "name" => "credentials", "status" => "ok", "detail" => "Google accepted the configured service-account credentials" }, { "name" => "admin_api", "status" => "ok", "detail" => "Admin API read succeeded" }, { "name" => "property_access", "status" => "ok", "detail" => "Read properties/#{remote.property_id}" } ] checks.concat(credential_file_checks) checks.concat(compatibility_checks) checks << clock_check checks << edit_capability_check data.run(desired_state.property_id, doctor_report_definition) checks << { "name" => "data_api", "status" => "ok", "detail" => "Data API read succeeded" } checks << { "name" => "credential_scope", "status" => "ok", "detail" => "This read-only command uses the Analytics read-only scope" } admin.capabilities.each do |name, available| checks << { "name" => name, "status" => available ? "ok" : "unsupported", "detail" => available ? "Installed client exposes this capability" : "Installed client lacks this capability" } end DoctorResult.new(checks:) end |
#each_report_page(name_or_definition, date_ranges: nil, page_size: DEFAULT_PAGE_SIZE, max_rows: MAX_EXPORT_ROWS) ⇒ Object
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/analytics_ops/workspace.rb', line 152 def each_report_page(name_or_definition, date_ranges: nil, page_size: DEFAULT_PAGE_SIZE, max_rows: MAX_EXPORT_ROWS) return enum_for(__method__, name_or_definition, date_ranges:, page_size:, max_rows:) unless block_given? definition, custom = resolved_report_definition(name_or_definition, kind: "standard") definition = definition.with_date_ranges(date_ranges) if date_ranges validate_report_definition(definition) if custom page_size = bounded_integer(page_size, "page_size", maximum: Reports::Definition::MAX_STANDARD_LIMIT) max_rows = bounded_integer(max_rows, "max_rows", maximum: MAX_EXPORT_ROWS) offset = definition.offset ending_offset = offset + max_rows while offset < ending_offset requested = [page_size, ending_offset - offset].min result = data.run( desired_state.property_id, definition.with_pagination(offset:, limit: requested) ) yield result returned = result.rows.length break if returned.zero? || offset + returned >= result.row_count offset += returned end end |
#export_report(name_or_definition, path:, date_ranges: nil, page_size: DEFAULT_PAGE_SIZE, max_rows: MAX_EXPORT_ROWS) ⇒ Object
178 179 180 181 182 |
# File 'lib/analytics_ops/workspace.rb', line 178 def export_report(name_or_definition, path:, date_ranges: nil, page_size: DEFAULT_PAGE_SIZE, max_rows: MAX_EXPORT_ROWS) pages = each_report_page(name_or_definition, date_ranges:, page_size:, max_rows:) Reports::CSVExport.write(path, pages) end |
#funnel(name, date_ranges: nil) ⇒ BigQuery::Result
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/analytics_ops/workspace.rb', line 231 def funnel(name, date_ranges: nil) definition = desired_state.funnels.fetch(name.to_s) do available = desired_state.funnels.keys.sort.join(", ") raise InvalidRequestError, "Unknown funnel #{name.inspect}; available funnels: #{available}" end unless desired_state.bigquery raise UnsupportedCapabilityError, "Funnel reports currently require the optional BigQuery configuration" end ranges = date_ranges || Reports::Period.resolve(last_days: Reports::Period::DEFAULT_DAYS, compare: false) dates = BigQuery::Definition.from_date_ranges("event_counts", ranges, limit: 1) bigquery_client.run_funnel( definition, start_suffix: dates.start_suffix, end_suffix: dates.end_suffix ) end |
#governance ⇒ Governance::Result
206 207 208 209 |
# File 'lib/analytics_ops/workspace.rb', line 206 def governance remote = admin.governance_snapshot(desired_state.property_id) Governance::Auditor.new(snapshot: remote, settings: desired_state.governance).call end |
#health(date_ranges: nil) ⇒ Health::Result
191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/analytics_ops/workspace.rb', line 191 def health(date_ranges: nil) ranges = date_ranges || Reports::Period.resolve(last_days: Reports::Period::DEFAULT_DAYS, compare: true) Health.validate_date_ranges!(ranges) definitions = Health::Definitions.for(ranges) reports = data.batch(desired_state.property_id, definitions) current_snapshot = snapshot current_plan = Planner.new(desired_state:, snapshot: current_snapshot).call Health::Runner.new( desired_state:, reports:, plan: current_plan, date_ranges: ranges ).call end |
#overview(date_ranges: nil) ⇒ Reports::OverviewResult
184 185 186 187 188 189 |
# File 'lib/analytics_ops/workspace.rb', line 184 def overview(date_ranges: nil) definitions = Reports::Catalog.overview definitions = definitions.map { |definition| definition.with_date_ranges(date_ranges) }.freeze if date_ranges reports = data.batch(desired_state.property_id, definitions) Reports::OverviewResult.new(property_id: desired_state.property_id, reports:) end |
#plan ⇒ Plan
91 92 93 |
# File 'lib/analytics_ops/workspace.rb', line 91 def plan Planner.new(desired_state:, snapshot:).call end |
#raw_report(name, date_ranges: nil, limit: 1_000) ⇒ Object
220 221 222 223 224 225 226 227 228 229 |
# File 'lib/analytics_ops/workspace.rb', line 220 def raw_report(name, date_ranges: nil, limit: 1_000) settings = desired_state.bigquery unless settings raise ConfigurationError, "BigQuery is not configured for this profile; see docs/bigquery.md" end ranges = date_ranges || Reports::Period.resolve(last_days: Reports::Period::DEFAULT_DAYS, compare: false) definition = BigQuery::Definition.from_date_ranges(name, ranges, limit:) bigquery_client.run(definition) end |
#realtime(name_or_definition = "realtime_events") ⇒ Reports::Result
112 113 114 115 116 |
# File 'lib/analytics_ops/workspace.rb', line 112 def realtime(name_or_definition = "realtime_events") definition, custom = resolved_report_definition(name_or_definition, kind: "realtime") validate_report_definition(definition) if custom data.run(desired_state.property_id, definition) end |
#report(name_or_definition, date_ranges: nil) ⇒ Object
105 106 107 108 109 110 |
# File 'lib/analytics_ops/workspace.rb', line 105 def report(name_or_definition, date_ranges: nil) definition, custom = resolved_report_definition(name_or_definition, kind: "standard") definition = definition.with_date_ranges(date_ranges) if date_ranges validate_report_definition(definition) if custom data.run(desired_state.property_id, definition) end |
#report_compatibility(name_or_definition) ⇒ Object
146 147 148 149 150 |
# File 'lib/analytics_ops/workspace.rb', line 146 def report_compatibility(name_or_definition) definition, = resolved_report_definition(name_or_definition, kind: "standard") validate_report_fields!(definition) data.check_compatibility(desired_state.property_id, definition) end |
#report_metadata(query: nil, kind: nil) ⇒ Reports::FieldList
118 119 120 121 |
# File 'lib/analytics_ops/workspace.rb', line 118 def (query: nil, kind: nil) fields = data.(desired_state.property_id).search(query, kind:) Reports::FieldList.new(property_id: desired_state.property_id, query:, kind: kind&.to_s, fields:) end |
#report_recipes ⇒ Reports::RecipeList
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/analytics_ops/workspace.rb', line 123 def report_recipes built_in = Reports::Catalog.names.map do |name| definition = Reports::Catalog.fetch(name) Reports::Recipe.new( name:, kind: definition.kind, source: "built_in", dimensions: definition.dimensions, metrics: definition.metrics ) end configured = desired_state.reports.map do |name, definition| Reports::Recipe.new( name:, kind: definition.kind, source: "configuration", dimensions: definition.dimensions, metrics: definition.metrics ) end Reports::RecipeList.new(recipes: (built_in + configured).sort_by { |recipe| [recipe.name, recipe.source] }) end |
#snapshot ⇒ Snapshot
83 84 85 |
# File 'lib/analytics_ops/workspace.rb', line 83 def snapshot admin.snapshot(desired_state.property_id) end |
#verify ⇒ Verification
101 102 103 |
# File 'lib/analytics_ops/workspace.rb', line 101 def verify Verification.new(plan:) end |