quickbase-extract 0.2.1__tar.gz → 0.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/.pre-commit-config.yaml +5 -6
  2. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/CHANGELOG.md +29 -0
  3. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/PKG-INFO +193 -2
  4. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/README.md +192 -0
  5. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/pyproject.toml +1 -2
  6. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/src/quickbase_extract/__init__.py +4 -13
  7. quickbase_extract-0.3.1/src/quickbase_extract/cache_sync.py +191 -0
  8. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/tests/conftest.py +10 -1
  9. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/tests/test_api_handlers.py +20 -4
  10. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/tests/test_cache_manager.py +0 -1
  11. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/tests/test_cache_orchestration.py +0 -1
  12. quickbase_extract-0.3.1/tests/test_cache_sync.py +364 -0
  13. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/tests/test_report_data.py +11 -3
  14. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/tests/test_report_metadata.py +0 -1
  15. quickbase_extract-0.2.1/src/quickbase_extract/cache_sync.py +0 -82
  16. quickbase_extract-0.2.1/tests/test_cache_sync.py +0 -119
  17. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/.editorconfig +0 -0
  18. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/.gitignore +0 -0
  19. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/.python-version +0 -0
  20. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/LICENSE.txt +0 -0
  21. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/TODO.md +0 -0
  22. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/src/quickbase_extract/api_handlers.py +0 -0
  23. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/src/quickbase_extract/cache_manager.py +0 -0
  24. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/src/quickbase_extract/cache_orchestration.py +0 -0
  25. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/src/quickbase_extract/config.py +0 -0
  26. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/src/quickbase_extract/py.typed +0 -0
  27. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/src/quickbase_extract/report_data.py +0 -0
  28. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/src/quickbase_extract/report_metadata.py +0 -0
  29. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/src/quickbase_extract/utils.py +0 -0
  30. {quickbase_extract-0.2.1 → quickbase_extract-0.3.1}/tests/test_utils.py +0 -0
@@ -8,14 +8,13 @@ repos:
8
8
  - id: check-yaml
9
9
  - id: debug-statements # Prevents accidental pdb/breakpoint commits
10
10
 
11
- - repo: https://github.com/psf/black
12
- rev: 23.12.1
13
- hooks:
14
- - id: black
15
- language_version: python3.12
16
-
17
11
  - repo: https://github.com/astral-sh/ruff-pre-commit
18
12
  rev: v0.1.11
19
13
  hooks:
20
14
  - id: ruff
21
15
  args: [--fix]
16
+ stages: [pre-commit]
17
+ - id: ruff-format
18
+ stages: [pre-commit]
19
+ - id: ruff # Run again to verify no more changes
20
+ stages: [pre-commit]
@@ -5,6 +5,35 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.3.1] - 2026-04-27
9
+
10
+ ### Fixed
11
+
12
+ - `complete_cache_refresh()` function now properly exported from `quickbase_extract` package for use in Lambda handlers
13
+
14
+ ## [0.3.0] - 2026-04-27
15
+
16
+ ### Added
17
+
18
+ - `complete_cache_refresh()` function in `cache_sync` module for selective cache refresh in development
19
+ - Support for granular cache refresh control:
20
+ - `force_all=True`: Refresh both metadata and data caches
21
+ - `force_metadata=True`: Refresh only metadata cache
22
+ - `force_data=True`: Refresh only data cache
23
+ - Cache refresh workflow: clear /tmp → fetch fresh from Quickbase → update S3 → re-sync to /tmp
24
+ - Manual development toggles in Lambda handlers for testing cache refresh without API changes
25
+ - Comprehensive test suite for complete cache refresh functionality
26
+
27
+ ### Changed
28
+
29
+ - Lambda workers can now force complete cache refresh for development/debugging by toggling code variables
30
+ - Cache refresh strategy clarified: selective refresh based on what changed (metadata vs data)
31
+
32
+ ### Fixed
33
+
34
+ - Dev workflow now supports forcing cache refresh without modifying Lambda event API
35
+ - Ensures /tmp and S3 are synchronized after cache refresh operations
36
+
8
37
  ## [0.2.1] - 2026-04-25
9
38
 
10
39
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quickbase-extract
3
- Version: 0.2.1
3
+ Version: 0.3.1
4
4
  Summary: Extract and cache Quickbase report data with built-in error handling and S3 support
5
5
  Project-URL: Homepage, https://github.com/tbrezler/quickbase-extract
6
6
  Project-URL: Repository, https://github.com/tbrezler/quickbase-extract.git
@@ -19,7 +19,6 @@ Requires-Python: >=3.12
19
19
  Requires-Dist: boto3>=1.26.0
20
20
  Requires-Dist: quickbase-api>=0.3.1
21
21
  Provides-Extra: dev
22
- Requires-Dist: black>=23.0; extra == 'dev'
23
22
  Requires-Dist: pytest-cov>=4.0; extra == 'dev'
24
23
  Requires-Dist: pytest>=7.0; extra == 'dev'
25
24
  Requires-Dist: ruff>=0.1.0; extra == 'dev'
@@ -955,10 +954,30 @@ def lambda_handler(event, context):
955
954
  - Cold start: Syncs cache from S3
956
955
  - Cache freshness: Auto-refreshes if stale
957
956
  - Data fetching: Queries Quickbase and caches results
957
+ - Development: Supports forcing complete cache refresh for testing
958
958
  """
959
959
  client = get_client()
960
960
  cache_mgr = get_cache_manager()
961
961
 
962
+ # OPTIONAL: Set to True to force cache refresh (for development/debugging only)
963
+ # Only one should be True at a time. force_all overrides the others.
964
+ FORCE_COMPLETE_CACHE_REFRESH_ALL = False
965
+ FORCE_COMPLETE_CACHE_REFRESH_METADATA = False
966
+ FORCE_COMPLETE_CACHE_REFRESH_DATA = False
967
+
968
+ # Force complete cache refresh if needed (dev/debugging only)
969
+ if (FORCE_COMPLETE_CACHE_REFRESH_ALL or FORCE_COMPLETE_CACHE_REFRESH_METADATA
970
+ or FORCE_COMPLETE_CACHE_REFRESH_DATA):
971
+ from quickbase_extract import complete_cache_refresh
972
+ complete_cache_refresh(
973
+ cache_manager=cache_mgr,
974
+ client=client,
975
+ report_configs=get_all_reports(),
976
+ force_all=FORCE_COMPLETE_CACHE_REFRESH_ALL,
977
+ force_metadata=FORCE_COMPLETE_CACHE_REFRESH_METADATA,
978
+ force_data=FORCE_COMPLETE_CACHE_REFRESH_DATA,
979
+ )
980
+
962
981
  # Step 1: Sync cache from S3 on cold start (only on first invocation)
963
982
  sync_from_s3_once(cache_mgr)
964
983
 
@@ -1563,6 +1582,48 @@ def lambda_handler(event, context):
1563
1582
  metadata = load_report_metadata_batch(cache_mgr, config)
1564
1583
  ```
1565
1584
 
1585
+ #### `complete_cache_refresh(cache_manager, client, report_configs, force_all=False, force_metadata=False, force_data=False)`
1586
+
1587
+ Completely refresh cache for development/debugging: clear /tmp, fetch fresh from Quickbase, update S3, re-sync to /tmp.
1588
+
1589
+ This is a development utility for forcing a complete cache refresh when report metadata or configurations change. Clears local /tmp cache, fetches fresh data from Quickbase, writes to S3, and re-syncs to /tmp.
1590
+
1591
+ **Parameters:**
1592
+ - `cache_manager` (CacheManager): Cache manager instance
1593
+ - `client`: Quickbase API client for fetching fresh data
1594
+ - `report_configs` (list[ReportConfig]): List of all ReportConfig instances to refresh
1595
+ - `force_all` (bool): If True, refresh both metadata and data. Defaults to False.
1596
+ - `force_metadata` (bool): If True (and `force_all` is False), refresh only metadata. Defaults to False.
1597
+ - `force_data` (bool): If True (and `force_all` is False), refresh only data. Defaults to False.
1598
+
1599
+ **Returns:** None
1600
+
1601
+ **Raises:**
1602
+ - `Exception`: If cache clearing or refresh operations fail
1603
+
1604
+ **Example:**
1605
+ ```python
1606
+ from quickbase_extract import complete_cache_refresh
1607
+
1608
+ # Refresh only metadata (after changing report configurations)
1609
+ complete_cache_refresh(
1610
+ cache_manager=cache_mgr,
1611
+ client=qb_client,
1612
+ report_configs=get_all_reports(),
1613
+ force_metadata=True
1614
+ )
1615
+
1616
+ # Refresh all (metadata + data)
1617
+ complete_cache_refresh(
1618
+ cache_manager=cache_mgr,
1619
+ client=qb_client,
1620
+ report_configs=get_all_reports(),
1621
+ force_all=True
1622
+ )
1623
+ ```
1624
+
1625
+ **Note:** This function is designed for development/debugging. To use in Lambda, add toggles to your handler (see "Development/Debug Mode" section below).
1626
+
1566
1627
  ### Query Execution with Retry Logic
1567
1628
 
1568
1629
  #### `handle_query(client, table_id, *, select=None, where=None, sort_by=None, group_by=None, options=None, description="", max_retries=3)`
@@ -2243,6 +2304,47 @@ ask_values = {"ask1": "value"} # No underscores
2243
2304
 
2244
2305
  ---
2245
2306
 
2307
+ ### Issue: Lambda has old cached data after I changed report metadata
2308
+
2309
+ **Symptom:** You updated a Quickbase report's fields, filters, or configuration, but your Lambda returns stale data.
2310
+
2311
+ **Cause:** Cache was loaded before your changes, and it hasn't become "stale" enough to auto-refresh yet.
2312
+
2313
+ **Solutions:**
2314
+
2315
+ 1. **Quick fix: Use force refresh toggle (development only)**
2316
+
2317
+ In your Lambda handler, temporarily set:
2318
+ ```python
2319
+ FORCE_COMPLETE_CACHE_REFRESH_METADATA = True
2320
+ ```
2321
+
2322
+ Upload new build, invoke Lambda, check logs for refresh. Then revert flag to `False`.
2323
+
2324
+ 2. **For immediate production fix:**
2325
+
2326
+ Manually delete files from S3:
2327
+ ```bash
2328
+ aws s3 rm s3://my-quickbase-cache-bucket/prod/cache/report_metadata/ --recursive
2329
+ ```
2330
+
2331
+ Next Lambda cold start will re-fetch fresh metadata.
2332
+
2333
+ 3. **To prevent in future:**
2334
+
2335
+ Reduce `metadata_stale_hours` threshold:
2336
+ ```python
2337
+ ensure_cache_freshness(
2338
+ client=client,
2339
+ cache_manager=cache_mgr,
2340
+ report_configs_all=get_all_reports(),
2341
+ report_configs_to_cache=get_reports_to_cache(),
2342
+ metadata_stale_hours=24 # Check daily instead of 30 days
2343
+ )
2344
+ ```
2345
+
2346
+ ---
2347
+
2246
2348
  ### Issue: Performance degradation over time
2247
2349
 
2248
2350
  **Symptom:** First request fast, subsequent requests slow.
@@ -2622,6 +2724,95 @@ def scheduled_cache_refresh(event, context):
2622
2724
  return {"statusCode": 200, "message": "Cache refreshed"}
2623
2725
  ```
2624
2726
 
2727
+ ### Development/Debug Mode: Forcing Complete Cache Refresh
2728
+
2729
+ When you modify report metadata or configurations in Quickbase, your Lambda may still use stale cached data. Use the force refresh toggles to clear everything and fetch fresh data.
2730
+
2731
+ #### When to Use
2732
+
2733
+ - You changed a report's filters or fields in Quickbase
2734
+ - You added/removed fields from a report
2735
+ - You renamed a report or table
2736
+ - You need to verify fresh data is being fetched
2737
+
2738
+ #### How to Use
2739
+
2740
+ 1. Open your Lambda handler code
2741
+ 2. Set one of the toggle flags to `True`:
2742
+
2743
+ ```python
2744
+ # In lambda_handler, find these lines:
2745
+ FORCE_COMPLETE_CACHE_REFRESH_ALL = False
2746
+ FORCE_COMPLETE_CACHE_REFRESH_METADATA = False
2747
+ FORCE_COMPLETE_CACHE_REFRESH_DATA = False
2748
+
2749
+ # Change to (example: refresh only metadata):
2750
+ FORCE_COMPLETE_CACHE_REFRESH_METADATA = True
2751
+ ```
2752
+
2753
+ 3. Upload new Lambda build
2754
+ 4. Invoke your Lambda (via API or CloudWatch event)
2755
+ 5. Check CloudWatch logs for cache refresh messages
2756
+ 6. **Revert the flag back to `False`** for normal operation
2757
+
2758
+ #### Flag Options
2759
+
2760
+ | Flag | What Gets Refreshed | Use When |
2761
+ |------|---------------------|----------|
2762
+ | `force_all=True` | Both metadata + data | Complete cache overhaul needed |
2763
+ | `force_metadata=True` | Only metadata | Report configuration changed |
2764
+ | `force_data=True` | Only data | Data needs fresh pull |
2765
+
2766
+ #### What Happens
2767
+
2768
+ When you trigger a force refresh:
2769
+
2770
+ 1. ✓ `/tmp` cache directories are deleted
2771
+ 2. ✓ Fresh data fetched from Quickbase API
2772
+ 3. ✓ Data written to S3
2773
+ 4. ✓ `/tmp` re-synced from updated S3
2774
+
2775
+ Your Lambda now has fresh data from Quickbase.
2776
+
2777
+ #### Example
2778
+
2779
+ ```python
2780
+ def lambda_handler(event, context):
2781
+ client = get_client()
2782
+ cache_mgr = get_cache_manager()
2783
+
2784
+ # Metadata changed in Quickbase? Force refresh it:
2785
+ FORCE_COMPLETE_CACHE_REFRESH_METADATA = True # ← Toggle this
2786
+
2787
+ if (FORCE_COMPLETE_CACHE_REFRESH_ALL or FORCE_COMPLETE_CACHE_REFRESH_METADATA
2788
+ or FORCE_COMPLETE_CACHE_REFRESH_DATA):
2789
+ from quickbase_extract import complete_cache_refresh
2790
+ complete_cache_refresh(
2791
+ cache_manager=cache_mgr,
2792
+ client=client,
2793
+ report_configs=get_all_reports(),
2794
+ force_metadata=FORCE_COMPLETE_CACHE_REFRESH_METADATA,
2795
+ )
2796
+
2797
+ # Rest of handler...
2798
+ ```
2799
+
2800
+ **CloudWatch logs will show:**
2801
+ ```
2802
+ WARNING: Starting complete cache refresh for: metadata (clearing /tmp, refreshing from Quickbase, updating S3...)
2803
+ DEBUG: Reset cache sync flag
2804
+ INFO: Fetching fresh data from Quickbase...
2805
+ INFO: Re-syncing /tmp from S3...
2806
+ WARNING: Complete cache refresh finished for metadata: /tmp and S3 now have fresh data from Quickbase
2807
+ ```
2808
+
2809
+ #### Important Notes
2810
+
2811
+ - **Don't leave toggles set to `True`** — revert to `False` after testing
2812
+ - **Only for development** — not a production workflow
2813
+ - Logs will show exactly what was refreshed
2814
+ - Safe to use — doesn't affect running processes, only next Lambda invocation
2815
+
2625
2816
  ## Advanced Usage
2626
2817
 
2627
2818
  ### Custom Report Configurations
@@ -928,10 +928,30 @@ def lambda_handler(event, context):
928
928
  - Cold start: Syncs cache from S3
929
929
  - Cache freshness: Auto-refreshes if stale
930
930
  - Data fetching: Queries Quickbase and caches results
931
+ - Development: Supports forcing complete cache refresh for testing
931
932
  """
932
933
  client = get_client()
933
934
  cache_mgr = get_cache_manager()
934
935
 
936
+ # OPTIONAL: Set to True to force cache refresh (for development/debugging only)
937
+ # Only one should be True at a time. force_all overrides the others.
938
+ FORCE_COMPLETE_CACHE_REFRESH_ALL = False
939
+ FORCE_COMPLETE_CACHE_REFRESH_METADATA = False
940
+ FORCE_COMPLETE_CACHE_REFRESH_DATA = False
941
+
942
+ # Force complete cache refresh if needed (dev/debugging only)
943
+ if (FORCE_COMPLETE_CACHE_REFRESH_ALL or FORCE_COMPLETE_CACHE_REFRESH_METADATA
944
+ or FORCE_COMPLETE_CACHE_REFRESH_DATA):
945
+ from quickbase_extract import complete_cache_refresh
946
+ complete_cache_refresh(
947
+ cache_manager=cache_mgr,
948
+ client=client,
949
+ report_configs=get_all_reports(),
950
+ force_all=FORCE_COMPLETE_CACHE_REFRESH_ALL,
951
+ force_metadata=FORCE_COMPLETE_CACHE_REFRESH_METADATA,
952
+ force_data=FORCE_COMPLETE_CACHE_REFRESH_DATA,
953
+ )
954
+
935
955
  # Step 1: Sync cache from S3 on cold start (only on first invocation)
936
956
  sync_from_s3_once(cache_mgr)
937
957
 
@@ -1536,6 +1556,48 @@ def lambda_handler(event, context):
1536
1556
  metadata = load_report_metadata_batch(cache_mgr, config)
1537
1557
  ```
1538
1558
 
1559
+ #### `complete_cache_refresh(cache_manager, client, report_configs, force_all=False, force_metadata=False, force_data=False)`
1560
+
1561
+ Completely refresh cache for development/debugging: clear /tmp, fetch fresh from Quickbase, update S3, re-sync to /tmp.
1562
+
1563
+ This is a development utility for forcing a complete cache refresh when report metadata or configurations change. Clears local /tmp cache, fetches fresh data from Quickbase, writes to S3, and re-syncs to /tmp.
1564
+
1565
+ **Parameters:**
1566
+ - `cache_manager` (CacheManager): Cache manager instance
1567
+ - `client`: Quickbase API client for fetching fresh data
1568
+ - `report_configs` (list[ReportConfig]): List of all ReportConfig instances to refresh
1569
+ - `force_all` (bool): If True, refresh both metadata and data. Defaults to False.
1570
+ - `force_metadata` (bool): If True (and `force_all` is False), refresh only metadata. Defaults to False.
1571
+ - `force_data` (bool): If True (and `force_all` is False), refresh only data. Defaults to False.
1572
+
1573
+ **Returns:** None
1574
+
1575
+ **Raises:**
1576
+ - `Exception`: If cache clearing or refresh operations fail
1577
+
1578
+ **Example:**
1579
+ ```python
1580
+ from quickbase_extract import complete_cache_refresh
1581
+
1582
+ # Refresh only metadata (after changing report configurations)
1583
+ complete_cache_refresh(
1584
+ cache_manager=cache_mgr,
1585
+ client=qb_client,
1586
+ report_configs=get_all_reports(),
1587
+ force_metadata=True
1588
+ )
1589
+
1590
+ # Refresh all (metadata + data)
1591
+ complete_cache_refresh(
1592
+ cache_manager=cache_mgr,
1593
+ client=qb_client,
1594
+ report_configs=get_all_reports(),
1595
+ force_all=True
1596
+ )
1597
+ ```
1598
+
1599
+ **Note:** This function is designed for development/debugging. To use in Lambda, add toggles to your handler (see "Development/Debug Mode" section below).
1600
+
1539
1601
  ### Query Execution with Retry Logic
1540
1602
 
1541
1603
  #### `handle_query(client, table_id, *, select=None, where=None, sort_by=None, group_by=None, options=None, description="", max_retries=3)`
@@ -2216,6 +2278,47 @@ ask_values = {"ask1": "value"} # No underscores
2216
2278
 
2217
2279
  ---
2218
2280
 
2281
+ ### Issue: Lambda has old cached data after I changed report metadata
2282
+
2283
+ **Symptom:** You updated a Quickbase report's fields, filters, or configuration, but your Lambda returns stale data.
2284
+
2285
+ **Cause:** Cache was loaded before your changes, and it hasn't become "stale" enough to auto-refresh yet.
2286
+
2287
+ **Solutions:**
2288
+
2289
+ 1. **Quick fix: Use force refresh toggle (development only)**
2290
+
2291
+ In your Lambda handler, temporarily set:
2292
+ ```python
2293
+ FORCE_COMPLETE_CACHE_REFRESH_METADATA = True
2294
+ ```
2295
+
2296
+ Upload new build, invoke Lambda, check logs for refresh. Then revert flag to `False`.
2297
+
2298
+ 2. **For immediate production fix:**
2299
+
2300
+ Manually delete files from S3:
2301
+ ```bash
2302
+ aws s3 rm s3://my-quickbase-cache-bucket/prod/cache/report_metadata/ --recursive
2303
+ ```
2304
+
2305
+ Next Lambda cold start will re-fetch fresh metadata.
2306
+
2307
+ 3. **To prevent in future:**
2308
+
2309
+ Reduce `metadata_stale_hours` threshold:
2310
+ ```python
2311
+ ensure_cache_freshness(
2312
+ client=client,
2313
+ cache_manager=cache_mgr,
2314
+ report_configs_all=get_all_reports(),
2315
+ report_configs_to_cache=get_reports_to_cache(),
2316
+ metadata_stale_hours=24 # Check daily instead of 30 days
2317
+ )
2318
+ ```
2319
+
2320
+ ---
2321
+
2219
2322
  ### Issue: Performance degradation over time
2220
2323
 
2221
2324
  **Symptom:** First request fast, subsequent requests slow.
@@ -2595,6 +2698,95 @@ def scheduled_cache_refresh(event, context):
2595
2698
  return {"statusCode": 200, "message": "Cache refreshed"}
2596
2699
  ```
2597
2700
 
2701
+ ### Development/Debug Mode: Forcing Complete Cache Refresh
2702
+
2703
+ When you modify report metadata or configurations in Quickbase, your Lambda may still use stale cached data. Use the force refresh toggles to clear everything and fetch fresh data.
2704
+
2705
+ #### When to Use
2706
+
2707
+ - You changed a report's filters or fields in Quickbase
2708
+ - You added/removed fields from a report
2709
+ - You renamed a report or table
2710
+ - You need to verify fresh data is being fetched
2711
+
2712
+ #### How to Use
2713
+
2714
+ 1. Open your Lambda handler code
2715
+ 2. Set one of the toggle flags to `True`:
2716
+
2717
+ ```python
2718
+ # In lambda_handler, find these lines:
2719
+ FORCE_COMPLETE_CACHE_REFRESH_ALL = False
2720
+ FORCE_COMPLETE_CACHE_REFRESH_METADATA = False
2721
+ FORCE_COMPLETE_CACHE_REFRESH_DATA = False
2722
+
2723
+ # Change to (example: refresh only metadata):
2724
+ FORCE_COMPLETE_CACHE_REFRESH_METADATA = True
2725
+ ```
2726
+
2727
+ 3. Upload new Lambda build
2728
+ 4. Invoke your Lambda (via API or CloudWatch event)
2729
+ 5. Check CloudWatch logs for cache refresh messages
2730
+ 6. **Revert the flag back to `False`** for normal operation
2731
+
2732
+ #### Flag Options
2733
+
2734
+ | Flag | What Gets Refreshed | Use When |
2735
+ |------|---------------------|----------|
2736
+ | `force_all=True` | Both metadata + data | Complete cache overhaul needed |
2737
+ | `force_metadata=True` | Only metadata | Report configuration changed |
2738
+ | `force_data=True` | Only data | Data needs fresh pull |
2739
+
2740
+ #### What Happens
2741
+
2742
+ When you trigger a force refresh:
2743
+
2744
+ 1. ✓ `/tmp` cache directories are deleted
2745
+ 2. ✓ Fresh data fetched from Quickbase API
2746
+ 3. ✓ Data written to S3
2747
+ 4. ✓ `/tmp` re-synced from updated S3
2748
+
2749
+ Your Lambda now has fresh data from Quickbase.
2750
+
2751
+ #### Example
2752
+
2753
+ ```python
2754
+ def lambda_handler(event, context):
2755
+ client = get_client()
2756
+ cache_mgr = get_cache_manager()
2757
+
2758
+ # Metadata changed in Quickbase? Force refresh it:
2759
+ FORCE_COMPLETE_CACHE_REFRESH_METADATA = True # ← Toggle this
2760
+
2761
+ if (FORCE_COMPLETE_CACHE_REFRESH_ALL or FORCE_COMPLETE_CACHE_REFRESH_METADATA
2762
+ or FORCE_COMPLETE_CACHE_REFRESH_DATA):
2763
+ from quickbase_extract import complete_cache_refresh
2764
+ complete_cache_refresh(
2765
+ cache_manager=cache_mgr,
2766
+ client=client,
2767
+ report_configs=get_all_reports(),
2768
+ force_metadata=FORCE_COMPLETE_CACHE_REFRESH_METADATA,
2769
+ )
2770
+
2771
+ # Rest of handler...
2772
+ ```
2773
+
2774
+ **CloudWatch logs will show:**
2775
+ ```
2776
+ WARNING: Starting complete cache refresh for: metadata (clearing /tmp, refreshing from Quickbase, updating S3...)
2777
+ DEBUG: Reset cache sync flag
2778
+ INFO: Fetching fresh data from Quickbase...
2779
+ INFO: Re-syncing /tmp from S3...
2780
+ WARNING: Complete cache refresh finished for metadata: /tmp and S3 now have fresh data from Quickbase
2781
+ ```
2782
+
2783
+ #### Important Notes
2784
+
2785
+ - **Don't leave toggles set to `True`** — revert to `False` after testing
2786
+ - **Only for development** — not a production workflow
2787
+ - Logs will show exactly what was refreshed
2788
+ - Safe to use — doesn't affect running processes, only next Lambda invocation
2789
+
2598
2790
  ## Advanced Usage
2599
2791
 
2600
2792
  ### Custom Report Configurations
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "quickbase-extract"
7
- version = "0.2.1"
7
+ version = "0.3.1"
8
8
  description = "Extract and cache Quickbase report data with built-in error handling and S3 support"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -31,7 +31,6 @@ dependencies = [
31
31
  dev = [
32
32
  "pytest>=7.0",
33
33
  "pytest-cov>=4.0",
34
- "black>=23.0",
35
34
  "ruff>=0.1.0",
36
35
  ]
37
36
 
@@ -28,12 +28,7 @@ import logging
28
28
  from importlib.metadata import version
29
29
 
30
30
  # API operations with error handling
31
- from quickbase_extract.api_handlers import (
32
- QuickbaseOperationError,
33
- handle_delete,
34
- handle_query,
35
- handle_upsert,
36
- )
31
+ from quickbase_extract.api_handlers import QuickbaseOperationError, handle_delete, handle_query, handle_upsert
37
32
 
38
33
  # Cache management
39
34
  from quickbase_extract.cache_manager import CacheManager
@@ -42,18 +37,13 @@ from quickbase_extract.cache_manager import CacheManager
42
37
  from quickbase_extract.cache_orchestration import ensure_cache_freshness
43
38
 
44
39
  # Cache sync
45
- from quickbase_extract.cache_sync import is_cache_synced, sync_from_s3_once
40
+ from quickbase_extract.cache_sync import complete_cache_refresh, is_cache_synced, sync_from_s3_once
46
41
 
47
42
  # Config
48
43
  from quickbase_extract.config import ReportConfig
49
44
 
50
45
  # Report data retrieval
51
- from quickbase_extract.report_data import (
52
- get_data,
53
- get_data_parallel,
54
- load_data,
55
- load_data_batch,
56
- )
46
+ from quickbase_extract.report_data import get_data, get_data_parallel, load_data, load_data_batch
57
47
 
58
48
  # Report metadata
59
49
  from quickbase_extract.report_metadata import (
@@ -77,6 +67,7 @@ __all__ = [
77
67
  # Cache management
78
68
  "CacheManager",
79
69
  "ensure_cache_freshness",
70
+ "complete_cache_refresh",
80
71
  "sync_from_s3_once",
81
72
  "is_cache_synced",
82
73
  # Config