refactor(docker): split requirements by role, slim enterprise bundle by default
Split requirements.txt into role-specific files: - requirements-backend.txt — FastAPI API runtime - requirements-agent.txt — Gradio/LangGraph agent (no embeddings) - requirements-embeddings.txt — opt-in sentence-transformers Default enterprise bundle (./build.sh bundle) builds slim agent without sentence-transformers/torch (~500 MB saved). Embeddings opt-in via ./build.sh bundle:embeddings <tag>. Embedding router degrades gracefully when package is absent (ImportError catch in _embedding_router.py). Updated Dockerfiles: - backend.Dockerfile → requirements-backend.txt - Dockerfile.agent → requirements-agent.txt + WITH_EMBEDDINGS build arg - all-in-one.Dockerfile → requirements-backend.txt Added embeddings variant to build.sh with full manifest/digest output. Hardened .dockerignore (cache, report, model, archive patterns). Other branch work: align git route mocks with async services, remove legacy agent test files superseded by contract tests.
This commit is contained in:
@@ -24,7 +24,7 @@ from src.core.logger import logger
|
||||
from src.core.superset_client import SupersetClient
|
||||
|
||||
|
||||
def test_dashboard_dataset_relations():
|
||||
def inspect_dashboard_dataset_relations():
|
||||
"""Test fetching dataset-to-dashboard relationships."""
|
||||
seed_trace_id()
|
||||
|
||||
@@ -59,18 +59,18 @@ def test_dashboard_dataset_relations():
|
||||
print(f" Published: {dashboard.get('published')}")
|
||||
|
||||
# Check for slices/charts
|
||||
if 'slices' in dashboard:
|
||||
logger.reason("Found slices in dashboard", payload={"dashboard_id": dashboard_id, "slice_count": len(dashboard['slices'])})
|
||||
for i, slice_data in enumerate(dashboard['slices'][:5]): # Show first 5
|
||||
print(f" Slice {i+1}:")
|
||||
if "slices" in dashboard:
|
||||
logger.reason("Found slices in dashboard", payload={"dashboard_id": dashboard_id, "slice_count": len(dashboard["slices"])})
|
||||
for i, slice_data in enumerate(dashboard["slices"][:5]): # Show first 5
|
||||
print(f" Slice {i + 1}:")
|
||||
print(f" ID: {slice_data.get('slice_id')}")
|
||||
print(f" Name: {slice_data.get('slice_name')}")
|
||||
# Check for datasource_id
|
||||
if 'datasource_id' in slice_data:
|
||||
if "datasource_id" in slice_data:
|
||||
print(f" Datasource ID: {slice_data['datasource_id']}")
|
||||
if 'datasource_name' in slice_data:
|
||||
if "datasource_name" in slice_data:
|
||||
print(f" Datasource Name: {slice_data['datasource_name']}")
|
||||
if 'datasource_type' in slice_data:
|
||||
if "datasource_type" in slice_data:
|
||||
print(f" Datasource Type: {slice_data['datasource_type']}")
|
||||
else:
|
||||
logger.reflect("No slices field in dashboard response", payload={"dashboard_id": dashboard_id})
|
||||
@@ -93,17 +93,14 @@ def test_dashboard_dataset_relations():
|
||||
# Method: Use Superset's related_objects API
|
||||
try:
|
||||
logger.reason("Querying related objects endpoint", payload={"dataset_id": dataset_id})
|
||||
related_objects = client.network.request(
|
||||
method="GET",
|
||||
endpoint=f"/dataset/{dataset_id}/related_objects"
|
||||
)
|
||||
related_objects = client.network.request(method="GET", endpoint=f"/dataset/{dataset_id}/related_objects")
|
||||
|
||||
logger.reason("Related objects response type", payload={"response_type": str(type(related_objects))})
|
||||
logger.reason("Related objects keys", payload={"keys": list(related_objects.keys()) if isinstance(related_objects, dict) else "N/A"})
|
||||
|
||||
# Check for dashboards in related objects
|
||||
if 'dashboards' in related_objects:
|
||||
dashboards = related_objects['dashboards']
|
||||
if "dashboards" in related_objects:
|
||||
dashboards = related_objects["dashboards"]
|
||||
logger.reason("Found dashboards for dataset", payload={"dataset_id": dataset_id, "count": len(dashboards)})
|
||||
|
||||
for dash in dashboards:
|
||||
@@ -111,11 +108,11 @@ def test_dashboard_dataset_relations():
|
||||
logger.reason("Dashboard entry", payload={"dashboard_id": dash.get("id"), "title": dash.get("dashboard_title", dash.get("title", "Unknown"))})
|
||||
else:
|
||||
logger.reason("Dashboard entry", payload={"dashboard": str(dash)})
|
||||
elif 'result' in related_objects:
|
||||
elif "result" in related_objects:
|
||||
# Some Superset versions use 'result' wrapper
|
||||
result = related_objects['result']
|
||||
if 'dashboards' in result:
|
||||
dashboards = result['dashboards']
|
||||
result = related_objects["result"]
|
||||
if "dashboards" in result:
|
||||
dashboards = result["dashboards"]
|
||||
logger.reason("Found dashboards for dataset (result wrapper)", payload={"dataset_id": dataset_id, "count": len(dashboards)})
|
||||
|
||||
for dash in dashboards:
|
||||
@@ -130,38 +127,36 @@ def test_dashboard_dataset_relations():
|
||||
except Exception as e:
|
||||
logger.explore("Error fetching related objects", payload={"dataset_id": dataset_id}, error=str(e))
|
||||
import traceback
|
||||
|
||||
traceback.print_exc()
|
||||
|
||||
# Method 2: Try to use the position_json from dashboard
|
||||
logger.reason("Analyzing dashboard position JSON")
|
||||
if 'position_json' in dashboard:
|
||||
position_data = json.loads(dashboard['position_json'])
|
||||
if "position_json" in dashboard:
|
||||
position_data = json.loads(dashboard["position_json"])
|
||||
logger.reason("Position data type", payload={"type": str(type(position_data))})
|
||||
|
||||
# Look for datasource references
|
||||
datasource_ids = set()
|
||||
if isinstance(position_data, dict):
|
||||
for key, value in position_data.items():
|
||||
if 'datasource' in key.lower() or key == 'DASHBOARD_VERSION_KEY':
|
||||
if "datasource" in key.lower() or key == "DASHBOARD_VERSION_KEY":
|
||||
logger.reason("Position entry", payload={"key": key, "value_type": str(type(value))})
|
||||
elif isinstance(position_data, list):
|
||||
logger.reason("Position data item count", payload={"count": len(position_data)})
|
||||
for item in position_data[:3]: # Show first 3
|
||||
logger.reason("Position item", payload={"item_type": str(type(item)), "keys": list(item.keys()) if isinstance(item, dict) else "N/A"})
|
||||
if isinstance(item, dict):
|
||||
if 'datasource_id' in item:
|
||||
datasource_ids.add(item['datasource_id'])
|
||||
if "datasource_id" in item:
|
||||
datasource_ids.add(item["datasource_id"])
|
||||
|
||||
if datasource_ids:
|
||||
logger.reason("Found datasource IDs in position data", payload={"datasource_ids": sorted(datasource_ids)})
|
||||
|
||||
# Save full response for analysis
|
||||
output_file = Path(__file__).parent / "dataset_dashboard_analysis.json"
|
||||
with open(output_file, 'w') as f:
|
||||
json.dump({
|
||||
'dashboard': dashboard,
|
||||
'dataset': dataset
|
||||
}, f, indent=2, default=str)
|
||||
with open(output_file, "w") as f:
|
||||
json.dump({"dashboard": dashboard, "dataset": dataset}, f, indent=2, default=str)
|
||||
logger.reason("Full response saved", payload={"output_file": str(output_file)})
|
||||
|
||||
except Exception as e:
|
||||
@@ -169,8 +164,12 @@ def test_dashboard_dataset_relations():
|
||||
raise
|
||||
|
||||
|
||||
test_dashboard_dataset_relations = inspect_dashboard_dataset_relations
|
||||
test_dashboard_dataset_relations.__test__ = False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_dashboard_dataset_relations()
|
||||
inspect_dashboard_dataset_relations()
|
||||
|
||||
# #endregion test_dataset_dashboard_relations_script
|
||||
# #endregion test_dataset_dashboard_relations_script
|
||||
|
||||
Reference in New Issue
Block a user