|
11 | 11 | process_list, |
12 | 12 | process_glp_device, |
13 | 13 | processed_data, |
14 | | - ensure_tokens_available, |
15 | 14 | get_all_device_inventory, |
16 | 15 | derive_site_ids_with_aps, |
17 | 16 | fetch_device_locations, |
18 | 17 | ) |
19 | 18 |
|
20 | | -CSV_COLUMNS = [ |
| 19 | +BASE_COLUMNS = [ |
21 | 20 | # Device information columns |
22 | 21 | "Serial Number", |
23 | 22 | "Mac Address", |
|
40 | 39 | "Subscription Tier", |
41 | 40 | "Subscription Type", |
42 | 41 | "Subscription End Time", |
43 | | - # Location fields (may be empty) |
| 42 | +] |
| 43 | + |
| 44 | +LOCATION_COLUMNS = [ |
44 | 45 | "Floorplan ID", |
45 | 46 | "Building ID", |
46 | 47 | "X Coordinate", |
47 | 48 | "Y Coordinate", |
48 | 49 | "Floor Coordinate Unit", |
49 | 50 | "Latitude", |
50 | 51 | "Longitude", |
51 | | - "Raw Location", |
52 | 52 | ] |
53 | 53 |
|
| 54 | +RAW_LOCATION_COLUMN = "Raw Location" |
| 55 | + |
54 | 56 | LOCATION_FETCH_WORKERS = 3 |
55 | 57 |
|
56 | 58 |
|
57 | 59 | def main(): |
58 | 60 | args = parse_args() |
59 | 61 | new_central_conn = NewCentralBase(token_info=args.credentials, log_level="ERROR") |
60 | | - try: |
61 | | - ensure_tokens_available(new_central_conn) |
62 | | - except Exception as e: |
63 | | - print(f"Error: {e}") |
64 | | - return |
65 | | - |
| 62 | + |
66 | 63 | devices_api = Devices() |
67 | 64 | subscriptions_api = Subscriptions() |
68 | 65 |
|
@@ -95,25 +92,38 @@ def main(): |
95 | 92 | else: |
96 | 93 | print("No site IDs with APs found; skipping floorplan/device-location fetch.") |
97 | 94 |
|
98 | | - processed = process_all_data(raw_data, processed_locations) |
| 95 | + processed = process_all_data( |
| 96 | + raw_data, |
| 97 | + processed_locations, |
| 98 | + processed_inventory, |
| 99 | + processed_devices, |
| 100 | + ) |
99 | 101 |
|
100 | 102 | # Save results to CSV and structured JSON |
101 | | - output = processed_data(**processed) |
102 | | - effective_columns = ( |
103 | | - CSV_COLUMNS |
104 | | - if args.include_raw_location |
105 | | - else [col for col in CSV_COLUMNS if col != "Raw Location"] |
| 103 | + output = processed_data( |
| 104 | + **processed, |
| 105 | + include_floorplan=(args.include_floorplan or args.include_raw_location), |
| 106 | + include_raw_location=args.include_raw_location, |
106 | 107 | ) |
| 108 | + |
| 109 | + # Build columns based on flags: omit location columns unless requested |
| 110 | + effective_columns = list(BASE_COLUMNS) |
| 111 | + if args.include_floorplan or args.include_raw_location: |
| 112 | + effective_columns += LOCATION_COLUMNS |
| 113 | + if args.include_raw_location: |
| 114 | + effective_columns.append(RAW_LOCATION_COLUMN) |
107 | 115 | if output: |
108 | 116 | # Prepare CSV rows: ensure Raw Location is serialized to a JSON string |
109 | 117 | csv_rows = [] |
110 | 118 | for row in output: |
111 | 119 | r = row.copy() |
112 | | - raw = r.get("Raw Location", "") |
113 | | - if isinstance(raw, (dict, list)): |
114 | | - r["Raw Location"] = json.dumps(raw, ensure_ascii=False) |
115 | | - elif raw is None: |
116 | | - r["Raw Location"] = "" |
| 120 | + # only serialize Raw Location when it's part of effective columns |
| 121 | + if RAW_LOCATION_COLUMN in effective_columns: |
| 122 | + raw = r.get(RAW_LOCATION_COLUMN, "") |
| 123 | + if isinstance(raw, (dict, list)): |
| 124 | + r[RAW_LOCATION_COLUMN] = json.dumps(raw, ensure_ascii=False) |
| 125 | + elif raw is None: |
| 126 | + r[RAW_LOCATION_COLUMN] = "" |
117 | 127 | csv_rows.append(r) |
118 | 128 |
|
119 | 129 | df = pd.DataFrame(csv_rows) |
@@ -199,15 +209,24 @@ def validate_file_format(file_path): |
199 | 209 | return file_path |
200 | 210 |
|
201 | 211 |
|
202 | | -def process_all_data(raw_data, processed_locations=None): |
203 | | - """Process raw API data into structured format. Accept optional processed_locations map.""" |
204 | | - processed_inventory = process_list( |
205 | | - _safe("device_inventory", raw_data), "serialNumber" |
206 | | - ) |
| 212 | +def process_all_data( |
| 213 | + raw_data, processed_locations=None, processed_inventory=None, processed_devices=None |
| 214 | +): |
| 215 | + """Process raw API data into structured format. |
| 216 | +
|
| 217 | + Accept optional precomputed `processed_inventory` and `processed_devices` to |
| 218 | + avoid recomputing large mappings when callers already have them. |
| 219 | + """ |
| 220 | + # compute only if not provided to preserve backward compatibility |
| 221 | + if processed_inventory is None: |
| 222 | + processed_inventory = process_list( |
| 223 | + _safe("device_inventory", raw_data), "serialNumber" |
| 224 | + ) |
| 225 | + if processed_devices is None: |
| 226 | + processed_devices = process_monitoring_data(_safe("monitoring_devices", raw_data)) |
| 227 | + |
207 | 228 | return { |
208 | | - "processed_devices": process_monitoring_data( |
209 | | - _safe("monitoring_devices", raw_data) |
210 | | - ), |
| 229 | + "processed_devices": processed_devices, |
211 | 230 | "processed_inventory": processed_inventory, |
212 | 231 | "processed_glp_devices": process_glp_device( |
213 | 232 | process_list(_safe("glp_devices", raw_data), "serialNumber"), |
|
0 commit comments