-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrequirements.txt
More file actions
225 lines (218 loc) · 11.9 KB
/
Copy pathrequirements.txt
File metadata and controls
225 lines (218 loc) · 11.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# Core scientific stack
pandas>=1.2.3
plotly>=6.9.0
requests>=2.27.1
retrying
setuptools
typing-extensions>=4.1.1
nest-asyncio
importlib-metadata
# Core Dash 4.x (pluggable backends, MCP, websocket callbacks)
# Flask is included by default. For other backends, install the extras below.
#
# Verified support matrix (dash-hook-my-ai `scripts/matrix.py` — real apps on
# each backend, with stock-Dash reproduction of the failure):
#
# Dash Flask FastAPI Quart
# 4.1.0 ok n/a (no pluggable backends) n/a
# 4.2.0 ok ok ok
# 4.3.0 ok BROKEN — every non-root 500s ok
# 4.4.0 ok ok ok
# 4.4.1 ok ok ok
#
# 4.3.0 added an early-return path guard to the ASGI middleware that returns
# before `set_current_request`, while the page catch-all still calls
# `get_current_request()` — so it raises. The catch-all is byte-identical
# between 4.2.0 and 4.3.0; only the middleware changed. 4.4.0 fixed it by
# setting the context inside the catch-all as well, which is belt-and-braces:
# a future middleware guard cannot reintroduce it. That is why 4.4.x is not
# merely "currently passing" but structurally safer than 4.2.0, which works
# only because a single upstream code path happens to cover it.
#
# `~=4.4.1` lets 4.4.2 patches flow without twenty pull requests, but blocks
# 4.5.0 so a minor bump goes through the matrix deliberately.
#
# Pinned for the most constrained backend network-wide, INCLUDING the Flask
# apps: DASH_BACKEND is an environment variable and this repo is a shared
# template, so a Flask deployment becomes a FastAPI deployment with one env
# change and no code change. A Flask-only pin would encode an assumption that
# a single deploy setting can invalidate.
dash~=4.4.1
dash-iconify>=0.1.2
dash-mantine-components>=2.8.0
dash-ag-grid
# Default backend (Flask is bundled but pinned here for clarity)
flask>=3.0.0
# Optional backends (uncomment / install to use):
# pip install "dash[fastapi]" -> FastAPI backend (async, websockets, MCP-friendly)
# pip install "dash[quart]" -> Quart backend (async Flask-compatible API)
# fastapi>=0.110.0
# quart>=0.19.0
# Documentation & Utilities
python-frontmatter>=1.0.0
# markdown2dash 0.1.2 declares `gunicorn>=21.2.0,<22.0.0` — a markdown parser
# pinning a WSGI server, and directly against the CVE-driven gunicorn>=23
# floor below. pip cannot resolve both, so markdown2dash is installed on its
# own line WITHOUT its dependency graph:
#
# pip install -r requirements.txt
# pip install --no-deps markdown2dash==0.1.2
#
# scripts/dev.sh, the Dockerfile, render.yaml and CI all do exactly that pair.
# Its real runtime dependencies are listed here instead (dash, dash-iconify
# and dash-mantine-components are already pinned above):
docutils!=0.21
jsonpath
mistune
pydantic>=2.3.0
python-dotenv>=1.0.0
# AI/LLM Integration & SEO
#
# Installed from PyPI. There is no vendored copy of this package in this repo
# any more — `vendor/` holds `dash_clerk_auth` alone. (2.1.0 and 2.3.1 were
# assigned during that package's development and never published.)
#
# 2.3.4 is the network standard: 2plot.ai and 2plot.dev both run it, and it
# is what makes the site-identity work below actually reach the surfaces. Its
# `resolve_site_title` picks the /llms.txt H1 and the llms-viewer brand chip
# from the home page's registered `name`, falling through generic nav labels
# ("Home", "Index", and Dash's default title "Dash") instead of publishing
# them as the site's identity. On a pre-2.3.4 artifact the viewer chip on this
# host reads a bare "Dash" — that is the fingerprint of a stale build.
#
# What the 2.3.x line changes, on this app specifically: `register_page_metadata` merges
# instead of assigning (no prose can be erased by a later bookkeeping call),
# the prerender reaches every visitor rather than only recognised crawlers,
# the Markdown renderer emits real anchors / code fences / tables / rules
# instead of literal text, and `register_network` publishes the cross-host
# directory that lib/network_directory.py feeds it. A page's llms.txt opens
# with a nav block pointing back at the site index and the network, and the
# same URL content-negotiates — agents get the Markdown byte for byte,
# browsers get it rendered behind a header carrying the network wordmark.
#
# The robots.txt crawler split doubles as the artifact fingerprint — pip
# metadata is not visible from outside. 2.3.2 allows OAI-SearchBot (ChatGPT
# search's crawler); 2.3.3 moves ClaudeBot (the actual *training* crawler) to
# Disallow while allowing the user-triggered and search fetchers Claude-User
# and Claude-SearchBot, and strips unexpanded directive lines from prose.
# tests/test_llms_routes.py asserts that split, and scripts/network_smoke.py
# asserts it against a live host, so a stale artifact fails a battery by name
# rather than serving quietly.
# 2.5.1 is the Tier-B SEO standard: configure_seo (icons, social card,
# publisher/sameAs), crawler <title> carrying the site name, per-page
# title/image_url/schema_type reaching the crawler document, /favicon.ico
# answered with a redirect instead of the app shell, and a prerender that
# no longer clobbers the browser's per-page <title>.
#
# 2.6.0 makes identity self-maintaining and the sitemap honest: icon
# autodiscovery from the assets folder (explicit configure_seo(icons=)
# still wins — this app declares, and tests/test_seo_icons.py pins that
# discovery agrees with the declaration), sitemap <lastmod> emitted
# verbatim from register_page_metadata(lastmod=) and OMITTED when unset
# (the invented daily dates are gone — Google discards a sitemap of lies
# wholesale), JSON-LD publisher.logo, and the llms.txt viewer banner
# de-dup. Floor, not pin: the fleet upgrades through this line.
# 2.8.0 floor (2026-08-29) — the LEDGER round. Not a feature this app can
# degrade without: `lib/analytics_tracker` imports `classify` and
# `_ledger.EVENT_FIELDS` at module scope and `run.py` calls
# `on_document_read` unconditionally, so anything lower is an ImportError at
# boot. What the floor buys: ONE classifier — `classify()` is the same
# vendor registry robots.txt is rendered from, so what this site SAYS about
# a vendor and what it COUNTS finally agree (the module's own UA lists filed
# ClaudeBot, Anthropic's TRAINING crawler, under "search" and counted every
# UA-less client as a person); the READ EVENT, one row per corpus document
# served, carrying tier, verdict, bytes and verified vendor identity, which
# `/admin/traffic` reads back; and `Vary: User-Agent` on the lane-split
# responses. 2.8.1 will write the resolved `policy` on every event — until
# then it is None and the rollup groups it as "default", which is why this
# floor does NOT wait for it.
#
# 2.7.1 floor (2026-08-23). TWO releases matter here and the floor names the
# later one deliberately — the fleet's floor round happens once.
#
# 2.7.0, the agent toll gate, is what this app CANNOT START without: it calls
# `configure_geo`, `LLMSConfig(panel=)`, `RobotsConfig(vendor_policy=)` and
# the rate ceiling unconditionally, so anything lower is an ImportError at
# boot rather than a degraded feature. It also carries the two defects this
# repo's own soak found and gated the tag on (BUGS-2.7.0.md #1 and #2): a
# `deny_countries` callable returning a nested object used to 500 EVERY
# request on EVERY surface, and a per-vendor block on a traditional crawler
# was enforced but never published in robots.txt. Both are reachable from the
# control board this site ships, which is why they were blocking.
#
# 2.7.1 is the standards fast-follow, published 36 minutes after 2.7.0 and
# additive throughout: `rel="describedby"` discovery relations on both
# document lanes plus HTTP `Link` headers, a `text/plain` Accept ramp for
# retrieval stacks that reject `text/markdown`, and a `llms-source-digest`
# that makes representation parity across the three lanes provable rather
# than plausible.
#
# 2.6.1 remains the previous rung and its reason is still live: below it the
# universal prerender ships VISIBLE to non-JS consumers.
dash-improve-my-llms[flask]>=2.8.0
# dash-improve-my-llms[fastapi]>=2.8.0 # Dash 4.4+ FastAPI backend
# dash-improve-my-llms[quart]>=2.8.0 # Dash 4.4+ Quart backend
# dash-improve-my-llms[all]>=2.8.0 # all three
# Clerk authentication (dash-clerk-auth, vendored — not on PyPI).
#
# Installed ALWAYS as of 1.4.1, gated at runtime: with no CLERK_* keys in the
# environment, lib/auth.py registers nothing and the site runs fully public —
# a fork inherits the capability, never a login wall. It moved into
# requirements because boilerplate.2plot.dev itself now runs the sign-in
# navigation (Clerk avatar + gate cards), and an uninstalled package meant
# the deployed reference site could not demonstrate the auth it documents.
#
# The floors below are the fleet security baseline, not a preference:
# clerk-backend-api 5.x capped cryptography at <47.0.0 — below the fixes for
# GHSA-537c-gmf6-5ccf (48.0.1), PYSEC-2026-3553/3554 (49.0.0) and
# PYSEC-2026-3552 (50.0.0). SDK 7.0.0 allows cryptography <51.0.0, and
# dash-clerk-auth 1.0.1 widened its cap to <8 exactly so applications can
# assert these floors rather than merely permit them.
#
# 1.0.4 (vendored 2026-08-21, from the live network certification's two
# finds): FastAPI auth endpoints are CALLABLE for the first time — 1.0.3
# registered them with an un-annotated request param, which FastAPI reads
# as a required query field (422 on every POST, swallowed client-side);
# inert here on Flask, fatal on any DASH_BACKEND=fastapi host. And the
# GHOST-COOKIE fresh-load reconciliation: a page that loads with ClerkJS
# signed-out while the server rendered signed-in now POSTs the signout
# and reloads once — the cross-host sign-out case no click shim can
# cover. revokeServerSession also verifies the response now (the
# assumption it didn't is what hid the 422 for a full release).
# 1.0.3's history: sign-out revocation on the click paths + live
# cross-tab transition, inline SVG default avatar, loud bad-redirect
# rejection. Our lib/auth.py signout shim remains an idempotent
# duplicate; the fleet-wide shim-retirement pass runs one clean release
# cycle after everyone is on the current line.
#
# 1.0.5 (vendored 2026-08-21): the return-trip stale gate — the last of
# the reconciliation cases, on the funnel's happiest path. Sign in from
# a satellite, return to the auth-gated page you started on, and the
# first server render happens BEFORE __dca_identity is minted, so the
# gate card persists until a manual refresh. 1.0.5 detects ClerkJS
# signed-in against a server-rendered signed-out page, syncs the
# session (getToken -> POST /api/auth/session) and reloads once, with a
# sessionStorage no-loop marker now shared by BOTH reconciliations
# (also closes a pre-existing loop case on 1.0.4's ghost path).
# PROVENANCE — the dist/ tarball is the release; there is no PyPI:
# sha256 a2f9062e15a69fc79deeaf76fcf1380907a961978db558b2aa227572cb2b74f3
# GENERAL RULE, twice-proven (1.0.4's 22117b20…, 1.0.5's first build):
# early builds go stale on sdist-shipped doc edits and are not
# distinguishable by name, size or date — ONLY the recorded sha admits
# a tarball into this file. Vendor from Dash-Clerk-Auth-Hook's dist/
# and verify before every copy.
./vendor/dash_clerk_auth-1.0.5.tar.gz
clerk-backend-api>=7.0.0,<8
cryptography>=50.0.0
# Production Servers
# - gunicorn -> WSGI (Flask)
# - uvicorn -> ASGI (FastAPI / Quart)
#
# gunicorn fronts every Flask deployment in this network, so the floor is the
# network's security baseline, not a convenience: 21.x carried two HTTP
# request-smuggling CVEs (CVE-2024-6827, CVE-2024-1135), both fixed by 23.0.
# CI asserts the installed version inside the built image — a transitive pin
# (markdown2dash asks for gunicorn<22) must never be allowed to drag the
# production server back under the floor without failing the build.
gunicorn>=23.0.0
# uvicorn[standard]>=0.27.0