nspasojevic commited on
Commit
f6c8f91
·
verified ·
1 Parent(s): 12c8db4

Web USD serving on the Space, dark (VIEWER_FORMAT unset = glb): indexing #72 v2 (84d79af5) runtime files

Browse files

supervisord files from #72 @84d79af5 (the '' case arm removed; supervisor 4.2.5 parser tests + real supervisord -n on noble/1.24 and bookworm/1.22: nginx RUNNING for unset/glb/usd/auto). nginx.conf.template = #72's hunks on prod's rail lists (#59's rail names ship with Artem's deploy). library_media.py unchanged (#72). Revert: restore 0fa97f4a's three docker files.

docker/hf-space/nginx.conf.template CHANGED
@@ -43,6 +43,13 @@ map $arg_v $slim_library_cache {
43
  "" "no-cache";
44
  default "public, max-age=31536000, immutable";
45
  }
 
 
 
 
 
 
 
46
  # <<< simready-central slim explorer (http) <<<
47
  server {
48
  listen __PORT__;
@@ -199,10 +206,28 @@ server {
199
  # category.qcode_property central:category: the Category tree (only the tree) reads the property the pipeline's
200
  # `categories` stage writes (pipeline/categories.py): the asset's Q-code, or oem:<HF owner> for a partner package,
201
  # so OEM > vendor scopes to that vendor and no asset is left Uncategorized. Search and parsing keep the Q-code.
 
 
 
 
202
  location = /config.js {
203
  default_type application/javascript;
204
  add_header Cache-Control "no-cache, must-revalidate" always;
205
- return 200 '(function(){var c="__CORPUS_NAME__";if(!c||c.indexOf("__")===0){c="usdsearch-dev";}window.__SERVER_MAPPING__={"usdsearch-dev":{"name":c+" (Hugging Face)","apiUrl":"","embedding_config":{"field_name":"siglip2-embedding.embedding","dimension":1536},"category":{"qcode_property":"central:category"},"features":{"download":__DOWNLOAD_ENABLED__,"s3UrlRemap":false,"seedDefaultScope":false,"railFilters":["profiles","simready_metadata_asset_license","category"],"railDefaults":["profiles","simready_metadata_asset_license","category"],"propertyAliases":{"wikidata_qcode":"simready_metadata_qcode"},"propertyFilterCombine":"and","submitContentUrl":"__SUBMIT_CONTENT_URL__"}}};window.__DEFAULT_SERVER__="usdsearch-dev";})();';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  }
207
  # index.html must always revalidate (covers the try_files fallback too): a swap or rollback
208
  # must not leave a browser holding an index.html that names deleted chunks.
@@ -296,7 +321,7 @@ server {
296
  location /library_media/ {
297
  root /app/hf-space-pipeline/.build; # .build/library_media/: outside .build/restore/, which the index restore empties
298
  try_files $uri @slim_not_found;
299
- types { application/json json; model/gltf-binary glb; video/mp4 mp4; image/jpeg jpg; image/webp webp; }
300
  default_type application/octet-stream;
301
  gzip_types application/json model/gltf-binary; # meshopt GLBs still shrink under gzip
302
  add_header Cache-Control $slim_library_cache always;
@@ -305,6 +330,47 @@ server {
305
  add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
306
  add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
307
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
  # Central's per-user surface is absent in this build: hard 404s, never the SPA's index.html.
309
  location ~ ^/(auth|packs|prefs|chats|created_assets|concept_images|meshy_quota|info|process|folder_hierarchy\.json|category_hierarchy\.json|api/create-chat|api/cad2simready)(/|$) {
310
  default_type application/json;
 
43
  "" "no-cache";
44
  default "public, max-age=31536000, immutable";
45
  }
46
+ # Web USD (/library_media/<id>/usd/*.usdc, below): a client whose Accept-Encoding names br gets the precompressed
47
+ # <file>.br sibling the media builder ships; `br;q=0` refuses it (RFC 9110 12.5.3). First match wins.
48
+ map $http_accept_encoding $slim_accepts_br {
49
+ default 0;
50
+ "~*(^|,)\s*br\s*;\s*q\s*=\s*0(\.0{0,3})?\s*(,|$)" 0;
51
+ "~*(^|,)\s*br\s*(;|,|$)" 1;
52
+ }
53
  # <<< simready-central slim explorer (http) <<<
54
  server {
55
  listen __PORT__;
 
206
  # category.qcode_property central:category: the Category tree (only the tree) reads the property the pipeline's
207
  # `categories` stage writes (pipeline/categories.py): the asset's Q-code, or oem:<HF owner> for a partner package,
208
  # so OEM > vendor scopes to that vendor and no asset is left Uncategorized. Search and parsing keep the Q-code.
209
+ # viewerFormat (Web USD's runtime switch, 2026-10-14): __VIEWER_FORMAT__ is rendered by the same sed from the
210
+ # Space variable VIEWER_FORMAT — glb (the default, also for anything but glb|usd|auto), usd or auto. The Explorer
211
+ # reads it over its baked REACT_APP_VIEWER_FORMAT, so web USD goes off with a variable and a restart, no rebuild;
212
+ # pipeline/library_media.py fetches the USD archives only when it is usd or auto.
213
  location = /config.js {
214
  default_type application/javascript;
215
  add_header Cache-Control "no-cache, must-revalidate" always;
216
+ return 200 '(function(){var c="__CORPUS_NAME__";if(!c||c.indexOf("__")===0){c="usdsearch-dev";}window.__SERVER_MAPPING__={"usdsearch-dev":{"name":c+" (Hugging Face)","apiUrl":"","embedding_config":{"field_name":"siglip2-embedding.embedding","dimension":1536},"category":{"qcode_property":"central:category"},"features":{"download":__DOWNLOAD_ENABLED__,"s3UrlRemap":false,"seedDefaultScope":false,"railFilters":["profiles","simready_metadata_asset_license","category"],"railDefaults":["profiles","simready_metadata_asset_license","category"],"propertyAliases":{"wikidata_qcode":"simready_metadata_qcode"},"propertyFilterCombine":"and","submitContentUrl":"__SUBMIT_CONTENT_URL__","viewerFormat":"__VIEWER_FORMAT__"}}};window.__DEFAULT_SERVER__="usdsearch-dev";})();';
217
+ }
218
+ # The Web USD reader (SimReady Central's explorer/scripts/copy-usd-reader.js: /static/usd-reader/<revision>/, a
219
+ # module worker's few small .js files and its ~2.3 MB WebAssembly). The stock gzip_types (and the server's line
220
+ # above) name no application/wasm, so without this the .wasm goes out raw: a .gz sibling the dist ships is sent as
221
+ # is (gzip_static), else it is gzipped here. Same files and folder as the /static/ alias above; longer prefix wins.
222
+ location /static/usd-reader/ {
223
+ alias /usr/share/nginx/explorer/static/usd-reader/;
224
+ types { application/wasm wasm; application/javascript js; }
225
+ default_type application/octet-stream;
226
+ gzip_static on;
227
+ gzip on;
228
+ gzip_comp_level 6;
229
+ gzip_vary on;
230
+ gzip_types application/wasm application/javascript;
231
  }
232
  # index.html must always revalidate (covers the try_files fallback too): a swap or rollback
233
  # must not leave a browser holding an index.html that names deleted chunks.
 
321
  location /library_media/ {
322
  root /app/hf-space-pipeline/.build; # .build/library_media/: outside .build/restore/, which the index restore empties
323
  try_files $uri @slim_not_found;
324
+ types { application/json json; model/gltf-binary glb; video/mp4 mp4; image/jpeg jpg; image/webp webp; image/ktx2 ktx2; image/png png; }
325
  default_type application/octet-stream;
326
  gzip_types application/json model/gltf-binary; # meshopt GLBs still shrink under gzip
327
  add_header Cache-Control $slim_library_cache always;
 
330
  add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
331
  add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
332
  }
333
+ # Web USD (manifest entry `usd`, SimReady Central's simready-web-usd/1): <id>/usd/{asset,hd,colliders}.usdc beside
334
+ # its KTX2 textures (<id>/usd/tex/*.ktx2, served by the location above: image/ktx2, Range, never gzipped — Basis
335
+ # is compressed already). A .usdc whose client accepts br is answered with the builder's precompressed
336
+ # <file>.usdc.br (Content-Encoding: br; whole, never a Range: a byte range of an encoded body is not one of the
337
+ # file), else, or without a .br sibling, with the file itself (Range as usual). Both vary on Accept-Encoding. No
338
+ # gzip_static: the builder writes no .gz, and the dynamic gzip never takes application/octet-stream.
339
+ location ~ ^/library_media/.+\.usdc$ {
340
+ root /app/hf-space-pipeline/.build;
341
+ error_page 418 = @slim_usdc_identity;
342
+ if ($slim_accepts_br = 0) { return 418; }
343
+ try_files $uri.br @slim_usdc_identity;
344
+ types { }
345
+ default_type application/octet-stream;
346
+ gzip off;
347
+ max_ranges 0;
348
+ add_header Content-Encoding br;
349
+ add_header Vary Accept-Encoding always;
350
+ add_header Cache-Control $slim_library_cache always;
351
+ add_header X-Content-Type-Options nosniff always;
352
+ add_header Access-Control-Allow-Origin "*" always;
353
+ add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
354
+ add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
355
+ }
356
+ location @slim_usdc_identity {
357
+ root /app/hf-space-pipeline/.build;
358
+ try_files $uri @slim_not_found;
359
+ types { }
360
+ default_type application/octet-stream;
361
+ gzip off;
362
+ add_header Vary Accept-Encoding always;
363
+ add_header Cache-Control $slim_library_cache always;
364
+ add_header X-Content-Type-Options nosniff always;
365
+ add_header Access-Control-Allow-Origin "*" always;
366
+ add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
367
+ add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
368
+ }
369
+ # A .br sibling is an encoding of its file, never a URL of its own.
370
+ location ~ ^/library_media/.+\.br$ {
371
+ default_type application/json;
372
+ return 404 '{"detail":"Not Found"}';
373
+ }
374
  # Central's per-user surface is absent in this build: hard 404s, never the SPA's index.html.
375
  location ~ ^/(auth|packs|prefs|chats|created_assets|concept_images|meshy_quota|info|process|folder_hierarchy\.json|category_hierarchy\.json|api/create-chat|api/cad2simready)(/|$) {
376
  default_type application/json;
docker/hf-space/supervisord-gpu.conf CHANGED
@@ -171,7 +171,10 @@ stderr_logfile=/dev/stderr
171
  stderr_logfile_maxbytes=0
172
 
173
  [program:nginx]
174
- command=/bin/sh -c "until curl -sf http://localhost:8000/health >/dev/null 2>&1 && curl -sf http://localhost:8010/docs >/dev/null 2>&1; do sleep 2; done; dl=false; case '%(ENV_DOWNLOAD_ENABLED)s' in [Tt]rue|1) if [ -f /app/hf-space-pipeline/.build/restore/hf-storage-api-catalog.yaml ]; then dl=true; else echo 'nginx: no hf-storage-api catalog, rendering download:false' >&2; fi;; esac; sed -e 's/__PORT__/%(ENV_PORT)s/' -e 's|__CORPUS_NAME__|%(ENV_CORPUS_NAME)s|g' -e 's/__DOWNLOAD_ENABLED__/'$dl'/' -e 's|__SUBMIT_CONTENT_URL__|%(ENV_SUBMIT_CONTENT_URL)s|g' /etc/nginx/hf-space.conf.template > /etc/nginx/conf.d/hf-space.conf && exec nginx -g 'daemon off;'"
 
 
 
175
  user=root
176
  autorestart=true
177
  startsecs=3
 
171
  stderr_logfile_maxbytes=0
172
 
173
  [program:nginx]
174
+ ; See docker/hf-space/supervisord.conf's own copy (identical command). Never put
175
+ ; a space before a ";" or "#" in a command: supervisord reads it as an inline
176
+ ; comment and cuts the command there (2026-10-15: nginx FATAL on prod).
177
+ command=/bin/sh -c "until curl -sf http://localhost:8000/health >/dev/null 2>&1 && curl -sf http://localhost:8010/docs >/dev/null 2>&1; do sleep 2; done; dl=false; case '%(ENV_DOWNLOAD_ENABLED)s' in [Tt]rue|1) if [ -f /app/hf-space-pipeline/.build/restore/hf-storage-api-catalog.yaml ]; then dl=true; else echo 'nginx: no hf-storage-api catalog, rendering download:false' >&2; fi;; esac; vf=glb; case $VIEWER_FORMAT in glb|usd|auto) vf=$VIEWER_FORMAT;; *) [ -z \"$VIEWER_FORMAT\" ] || echo 'nginx: VIEWER_FORMAT is not glb, usd or auto: rendering viewerFormat glb' >&2;; esac; sed -e 's/__PORT__/%(ENV_PORT)s/' -e 's|__CORPUS_NAME__|%(ENV_CORPUS_NAME)s|g' -e 's/__DOWNLOAD_ENABLED__/'$dl'/' -e 's|__SUBMIT_CONTENT_URL__|%(ENV_SUBMIT_CONTENT_URL)s|g' -e 's/__VIEWER_FORMAT__/'$vf'/' /etc/nginx/hf-space.conf.template > /etc/nginx/conf.d/hf-space.conf && exec nginx -g 'daemon off;'"
178
  user=root
179
  autorestart=true
180
  startsecs=3
docker/hf-space/supervisord.conf CHANGED
@@ -210,7 +210,12 @@ stderr_logfile_maxbytes=0
210
  ; deepsearch-api used to follow directly before nginx sat in front of it.
211
  ; %(ENV_PORT)s is substituted by supervisord itself, so no extra templating
212
  ; tool (envsubst etc.) is needed in the image.
213
- command=/bin/sh -c "until curl -sf http://localhost:8000/health >/dev/null 2>&1 && curl -sf http://localhost:8010/docs >/dev/null 2>&1; do sleep 2; done; dl=false; case '%(ENV_DOWNLOAD_ENABLED)s' in [Tt]rue|1) if [ -f /app/hf-space-pipeline/.build/restore/hf-storage-api-catalog.yaml ]; then dl=true; else echo 'nginx: no hf-storage-api catalog, rendering download:false' >&2; fi;; esac; sed -e 's/__PORT__/%(ENV_PORT)s/' -e 's|__CORPUS_NAME__|%(ENV_CORPUS_NAME)s|g' -e 's/__DOWNLOAD_ENABLED__/'$dl'/' -e 's|__SUBMIT_CONTENT_URL__|%(ENV_SUBMIT_CONTENT_URL)s|g' /etc/nginx/hf-space.conf.template > /etc/nginx/conf.d/hf-space.conf && exec nginx -g 'daemon off;'"
 
 
 
 
 
214
  user=root
215
  autorestart=true
216
  startsecs=3
 
210
  ; deepsearch-api used to follow directly before nginx sat in front of it.
211
  ; %(ENV_PORT)s is substituted by supervisord itself, so no extra templating
212
  ; tool (envsubst etc.) is needed in the image.
213
+ ;
214
+ ; Never put a space before a ";" or "#" in a command: supervisord's parser
215
+ ; reads " ;" and " #" as the start of an inline comment and cuts the command
216
+ ; there (2026-10-15: a " ;;" case arm left nginx FATAL, "No closing
217
+ ; quotation"). tests/test_hf_space_runtime.py parses with supervisor itself.
218
+ command=/bin/sh -c "until curl -sf http://localhost:8000/health >/dev/null 2>&1 && curl -sf http://localhost:8010/docs >/dev/null 2>&1; do sleep 2; done; dl=false; case '%(ENV_DOWNLOAD_ENABLED)s' in [Tt]rue|1) if [ -f /app/hf-space-pipeline/.build/restore/hf-storage-api-catalog.yaml ]; then dl=true; else echo 'nginx: no hf-storage-api catalog, rendering download:false' >&2; fi;; esac; vf=glb; case $VIEWER_FORMAT in glb|usd|auto) vf=$VIEWER_FORMAT;; *) [ -z \"$VIEWER_FORMAT\" ] || echo 'nginx: VIEWER_FORMAT is not glb, usd or auto: rendering viewerFormat glb' >&2;; esac; sed -e 's/__PORT__/%(ENV_PORT)s/' -e 's|__CORPUS_NAME__|%(ENV_CORPUS_NAME)s|g' -e 's/__DOWNLOAD_ENABLED__/'$dl'/' -e 's|__SUBMIT_CONTENT_URL__|%(ENV_SUBMIT_CONTENT_URL)s|g' -e 's/__VIEWER_FORMAT__/'$vf'/' /etc/nginx/hf-space.conf.template > /etc/nginx/conf.d/hf-space.conf && exec nginx -g 'daemon off;'"
219
  user=root
220
  autorestart=true
221
  startsecs=3