upstrace 0.1.0__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.
- upstrace-0.1.0/.dockerignore +17 -0
- upstrace-0.1.0/.env.example +11 -0
- upstrace-0.1.0/.github/workflows/nightly.yml +87 -0
- upstrace-0.1.0/.gitignore +19 -0
- upstrace-0.1.0/Dockerfile +61 -0
- upstrace-0.1.0/LICENSE +9 -0
- upstrace-0.1.0/PKG-INFO +1078 -0
- upstrace-0.1.0/README.md +1042 -0
- upstrace-0.1.0/app/index.html +12 -0
- upstrace-0.1.0/app/package-lock.json +1815 -0
- upstrace-0.1.0/app/package.json +19 -0
- upstrace-0.1.0/app/src/App.jsx +156 -0
- upstrace-0.1.0/app/src/api.js +27 -0
- upstrace-0.1.0/app/src/components/FaultPanel.jsx +31 -0
- upstrace-0.1.0/app/src/components/IncidentDetail.jsx +135 -0
- upstrace-0.1.0/app/src/components/IncidentList.jsx +37 -0
- upstrace-0.1.0/app/src/components/LineageGraph.jsx +114 -0
- upstrace-0.1.0/app/src/components/MetricChart.jsx +329 -0
- upstrace-0.1.0/app/src/main.jsx +10 -0
- upstrace-0.1.0/app/src/styles.css +329 -0
- upstrace-0.1.0/app/vite.config.js +19 -0
- upstrace-0.1.0/data/demo/yellow_tripdata_demo.parquet +0 -0
- upstrace-0.1.0/docs/eval-results-before-partitioning.md +82 -0
- upstrace-0.1.0/docs/eval-results.md +50 -0
- upstrace-0.1.0/docs/model-comparison.md +76 -0
- upstrace-0.1.0/docs/screenshot-chart.png +0 -0
- upstrace-0.1.0/docs/screenshot-incident.png +0 -0
- upstrace-0.1.0/docs/second-dataset.md +154 -0
- upstrace-0.1.0/pyproject.toml +58 -0
- upstrace-0.1.0/requirements.txt +6 -0
- upstrace-0.1.0/scripts/build_demo_warehouse.py +53 -0
- upstrace-0.1.0/scripts/download_data.py +71 -0
- upstrace-0.1.0/scripts/load_duckdb.py +86 -0
- upstrace-0.1.0/scripts/make_demo_sample.py +55 -0
- upstrace-0.1.0/src/upstrace/__init__.py +1 -0
- upstrace-0.1.0/src/upstrace/api.py +371 -0
- upstrace-0.1.0/src/upstrace/cli.py +479 -0
- upstrace-0.1.0/src/upstrace/config.py +26 -0
- upstrace-0.1.0/src/upstrace/drift.py +524 -0
- upstrace-0.1.0/src/upstrace/evaluate.py +255 -0
- upstrace-0.1.0/src/upstrace/explain.py +121 -0
- upstrace-0.1.0/src/upstrace/faults.py +86 -0
- upstrace-0.1.0/src/upstrace/lineage.py +47 -0
- upstrace-0.1.0/src/upstrace/llm.py +208 -0
- upstrace-0.1.0/src/upstrace/manifest.py +84 -0
- upstrace-0.1.0/src/upstrace/notify.py +237 -0
- upstrace-0.1.0/src/upstrace/profiler.py +268 -0
- upstrace-0.1.0/src/upstrace/rca.py +128 -0
- upstrace-0.1.0/src/upstrace/report.py +640 -0
- upstrace-0.1.0/src/upstrace/scenarios.py +221 -0
- upstrace-0.1.0/src/upstrace/settings.py +286 -0
- upstrace-0.1.0/src/upstrace/warehouse.py +66 -0
- upstrace-0.1.0/transform/.user.yml +1 -0
- upstrace-0.1.0/transform/dbt_project.yml +18 -0
- upstrace-0.1.0/transform/models/marts/_models.yml +30 -0
- upstrace-0.1.0/transform/models/marts/agg_daily_quality.sql +16 -0
- upstrace-0.1.0/transform/models/marts/agg_daily_revenue.sql +12 -0
- upstrace-0.1.0/transform/models/marts/fct_trips.sql +37 -0
- upstrace-0.1.0/transform/models/staging/_models.yml +26 -0
- upstrace-0.1.0/transform/models/staging/_sources.yml +9 -0
- upstrace-0.1.0/transform/models/staging/stg_trips.sql +47 -0
- upstrace-0.1.0/transform/profiles.yml +7 -0
- upstrace-0.1.0/transform/tests/assert_revenue_never_negative.sql +9 -0
- upstrace-0.1.0/upstrace.yml +35 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Copy this file to .env and fill in your own key.
|
|
2
|
+
# Free key: https://console.groq.com (no card required)
|
|
3
|
+
|
|
4
|
+
GROQ_API_KEY=
|
|
5
|
+
UPSTRACE_LLM_PROVIDER=groq
|
|
6
|
+
|
|
7
|
+
# Alternatives:
|
|
8
|
+
# GEMINI_API_KEY= # https://aistudio.google.com
|
|
9
|
+
# UPSTRACE_LLM_PROVIDER=gemini
|
|
10
|
+
# UPSTRACE_LLM_PROVIDER=ollama # local, no key needed
|
|
11
|
+
# UPSTRACE_LLM_MODEL= # override the default model
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
name: nightly
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
- cron: "0 6 * * *"
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
pages: write
|
|
13
|
+
id-token: write
|
|
14
|
+
|
|
15
|
+
concurrency:
|
|
16
|
+
group: pages
|
|
17
|
+
cancel-in-progress: false
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
self-check:
|
|
21
|
+
name: Detects a real fault, and nothing else
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
|
|
24
|
+
environment:
|
|
25
|
+
name: github-pages
|
|
26
|
+
url: ${{ steps.deploy.outputs.page_url }}
|
|
27
|
+
|
|
28
|
+
env:
|
|
29
|
+
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
|
|
30
|
+
UPSTRACE_LLM_PROVIDER: groq
|
|
31
|
+
UPSTRACE_LLM_MODEL: qwen/qwen3.8-27b
|
|
32
|
+
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@v4
|
|
35
|
+
|
|
36
|
+
- uses: actions/setup-python@v5
|
|
37
|
+
with:
|
|
38
|
+
python-version: "3.11"
|
|
39
|
+
|
|
40
|
+
- name: Install
|
|
41
|
+
run: pip install -e . "dbt-core==1.10.*" "dbt-duckdb==1.9.*"
|
|
42
|
+
|
|
43
|
+
- name: Build the demo warehouse
|
|
44
|
+
run: |
|
|
45
|
+
cp data/demo/*.parquet data/
|
|
46
|
+
python scripts/build_demo_warehouse.py
|
|
47
|
+
|
|
48
|
+
# Half the value of a data quality tool is not crying wolf. This asserts
|
|
49
|
+
# that two profile runs over unchanged data produce nothing at all - not
|
|
50
|
+
# even a warning.
|
|
51
|
+
|
|
52
|
+
- name: No false positives on unchanged data
|
|
53
|
+
run: upstrace drift --fail-on warning
|
|
54
|
+
|
|
55
|
+
# The other half is actually catching something. A green badge that only
|
|
56
|
+
# proved the tool stays quiet would be worthless.
|
|
57
|
+
|
|
58
|
+
- name: A real fault is detected
|
|
59
|
+
run: |
|
|
60
|
+
upstrace fault unit-change
|
|
61
|
+
cd transform && dbt run --profiles-dir . && cd ..
|
|
62
|
+
upstrace profile
|
|
63
|
+
if upstrace drift --fail-on critical; then
|
|
64
|
+
echo "::error::A unit change was injected and no critical signal was raised."
|
|
65
|
+
exit 1
|
|
66
|
+
fi
|
|
67
|
+
echo "Fault detected, as expected."
|
|
68
|
+
|
|
69
|
+
- name: Root cause
|
|
70
|
+
run: upstrace rca
|
|
71
|
+
|
|
72
|
+
# The warehouse still holds the injected fault, so the published page shows
|
|
73
|
+
# a real incident rather than an empty all-clear.
|
|
74
|
+
|
|
75
|
+
- name: Build the report
|
|
76
|
+
run: |
|
|
77
|
+
mkdir -p site
|
|
78
|
+
upstrace report -o site/index.html
|
|
79
|
+
|
|
80
|
+
- uses: actions/configure-pages@v5
|
|
81
|
+
|
|
82
|
+
- uses: actions/upload-pages-artifact@v3
|
|
83
|
+
with:
|
|
84
|
+
path: site
|
|
85
|
+
|
|
86
|
+
- id: deploy
|
|
87
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
.venv/
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.pyc
|
|
4
|
+
data/*
|
|
5
|
+
!data/demo/
|
|
6
|
+
data/demo/*
|
|
7
|
+
!data/demo/*.parquet
|
|
8
|
+
warehouse/
|
|
9
|
+
.env
|
|
10
|
+
.DS_Store
|
|
11
|
+
transform/target/
|
|
12
|
+
transform/dbt_packages/
|
|
13
|
+
transform/logs/
|
|
14
|
+
*.egg-info/
|
|
15
|
+
build/
|
|
16
|
+
dist/
|
|
17
|
+
app/node_modules/
|
|
18
|
+
app/static/
|
|
19
|
+
cache/
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# ---- stage 1: build the React SPA -------------------------------------------
|
|
2
|
+
FROM node:22-slim AS frontend
|
|
3
|
+
WORKDIR /app
|
|
4
|
+
COPY app/package.json app/package-lock.json ./
|
|
5
|
+
RUN npm ci
|
|
6
|
+
COPY app/ ./
|
|
7
|
+
RUN npm run build
|
|
8
|
+
|
|
9
|
+
# ---- stage 2: the tool, with no data of its own -----------------------------
|
|
10
|
+
# Build this one to run Upstrace against your own dbt project:
|
|
11
|
+
# docker build --target runtime -t upstrace .
|
|
12
|
+
# docker run -v /path/to/your/project:/project -w /project \
|
|
13
|
+
# -p 7860:7860 upstrace uvicorn upstrace.api:app --host 0.0.0.0 --port 7860
|
|
14
|
+
# upstrace.yml is discovered by walking up from the working directory, and every
|
|
15
|
+
# path inside it resolves relative to that file - so the mounted project's
|
|
16
|
+
# warehouse and dbt project are found, while the package stays at /srv.
|
|
17
|
+
FROM python:3.11-slim AS runtime
|
|
18
|
+
|
|
19
|
+
ENV PYTHONUNBUFFERED=1 \
|
|
20
|
+
PIP_NO_CACHE_DIR=1 \
|
|
21
|
+
UPSTRACE_LLM_PROVIDER=mock
|
|
22
|
+
|
|
23
|
+
WORKDIR /srv
|
|
24
|
+
|
|
25
|
+
COPY pyproject.toml README.md ./
|
|
26
|
+
COPY src/ src/
|
|
27
|
+
|
|
28
|
+
# Editable install, deliberately. It keeps the package rooted at /srv, so
|
|
29
|
+
# PROJECT_ROOT still resolves to the repo - app/static where the API expects it.
|
|
30
|
+
# A normal install would move the package to site-packages and break that.
|
|
31
|
+
RUN pip install -e . "dbt-core==1.10.*" "dbt-duckdb==1.9.*"
|
|
32
|
+
|
|
33
|
+
COPY --from=frontend /app/static app/static
|
|
34
|
+
|
|
35
|
+
RUN useradd -m -u 1000 user && chown -R user:user /srv
|
|
36
|
+
USER user
|
|
37
|
+
|
|
38
|
+
EXPOSE 7860
|
|
39
|
+
CMD ["uvicorn", "upstrace.api:app", "--host", "0.0.0.0", "--port", "7860"]
|
|
40
|
+
|
|
41
|
+
# ---- stage 3: the public demo -----------------------------------------------
|
|
42
|
+
# Same tool, plus a 400k-row sample of the NYC taxi data and a warehouse built
|
|
43
|
+
# at image build time. This is what Hugging Face Spaces runs: it starts in under
|
|
44
|
+
# a second and needs no external data source.
|
|
45
|
+
FROM runtime AS demo
|
|
46
|
+
|
|
47
|
+
USER root
|
|
48
|
+
|
|
49
|
+
COPY upstrace.yml ./
|
|
50
|
+
COPY transform/ transform/
|
|
51
|
+
COPY scripts/ scripts/
|
|
52
|
+
COPY cache/ cache/
|
|
53
|
+
COPY data/demo/yellow_tripdata_demo.parquet data/
|
|
54
|
+
|
|
55
|
+
RUN python scripts/build_demo_warehouse.py
|
|
56
|
+
|
|
57
|
+
RUN chown -R user:user /srv
|
|
58
|
+
USER user
|
|
59
|
+
|
|
60
|
+
EXPOSE 7860
|
|
61
|
+
CMD ["uvicorn", "upstrace.api:app", "--host", "0.0.0.0", "--port", "7860"]
|
upstrace-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ashwin Gururaj
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|