Get Python apps working again after Viceroy WIT updates etc. - #10

Merged
erikrose merged 23 commits into
mainfrom
get-wasiless-working-with-flask
Oct 20, 2025
Merged

Get Python apps working again after Viceroy WIT updates etc.#10
erikrose merged 23 commits into
mainfrom
get-wasiless-working-with-flask

Conversation

@erikrose

@erikroseerikrose commented Oct 16, 2025

Copy link
Copy Markdown
Member

Both example apps now link, run, and pass tests happily. We do this by interposing wasiless, a null implementation of the WASI routines outside Viceroy's purview, which satisfies CPython's importing (and sometimes calling) of them: things like ttys and FSs.

The only caveat is you have to use the erik/python-sdk-2 branch of Viceroy, which increases the allowed number of memories to 2 to allow the wasiless component to fit. The CI job uses a tag on that branch.

Also…

  • Switch to self-hosted testrunners, because the GH-hosted ones will quit working in our org in a few days. Bonus: building Viceroy takes 25s instead of 2m.
  • Cache builds of Viceroy and other tools for speed, bringing a warm CI run to about 1m. We could cache further if we wanted.
  • Sync up with Viceroy's latest WIT files.
  • Support an env var to prefer a specific path to Viceroy.

erikroseand others added 14 commits October 8, 2025 10:41
This shouldn't matter, but it's one less thing to conflict.
…stubs.
Note both flask-app.wasm and wit-bottle.wasm have identical WIT (and thus imports), so one should link if the other does.
Current error:
```
% wac compose --dep fastly:wasiless=../wasiless/componentized.wasm --dep app:component=build/wit-bottle.wasm -o composed.wasm wrap_app_in_wasiless.wac
error: the encoding of the graph failed validation
Caused by:
type mismatch for import `wasi:filesystem/types@0.2.0`
type mismatch in instance export `input-stream`
resource types are not the same (ResourceId { globally_unique_id: 2, contextually_unique_id: 134 } vs. ResourceId { globally_unique_id: 2, contextually_unique_id: 6 }) (at offset 0x2916624)
```
…he imports of `wit-bottle.wasm`.
In other words, this "should work".
Specifically, revise the wac to not import anything that is provided by the Compute `service-imports` world. Those items should be provided directly by the host (Viceroy or similar), as then it will actually be functional.
Add in `poll`, as Python imports it but `service-imports` does not (so it's not provided to services by the host).
…bbcc9e92e43545224.
I don't know that it makes any difference, but now it matches wasiless'.
This solves the immediate `pollable` type mismatch when `wac`ing together a Python component.
It makes it easier for me to follow.
That means deleting it and referencing the `fastly:compute/service` world directly. It covers all the imports and exports we need.
Then use wasm-tools component new to transform to a component
for use with wac.
This illustrates the contrast in behavior between leaf and non-leaf WIT interfaces and positions us to move forward inch by inch.
As far as Viceroy is concerned, we need export only `http-incoming`.
…ink and run, culminating in a Python traceback.
Delegate to the wasiless repo for building the wasiless component.
@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch 2 times, most recently from 2dd32f4 to 186413dCompareOctober 16, 2025 21:37
@fastly-forge-auditor

Copy link
Copy Markdown

⚠️⚠️⚠️ Future executions of the workflow Python CI will be aborted starting in 12 days due to the usage of non-approved GitHub runner labels.
Offending label: [ubuntu-latest]


Please, contact Developer Platform at #ci-support if you need help using Forge runners

@fastly-forge-auditor

Copy link
Copy Markdown

⚠️⚠️⚠️ Future executions of the workflow Python CI will be aborted starting in 11 days due to the usage of non-approved GitHub runner labels.
Offending label: [ubuntu-latest]


Please, contact Developer Platform at #ci-support if you need help using Forge runners

@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch from 4909933 to 85e8fdbCompareOctober 17, 2025 15:44
@erikrose

erikrose commented Oct 17, 2025

Copy link
Copy Markdown
MemberAuthor

The problem is that wasiless can't be checked out as a submodule because it's an Internal repo. [Fixed.]

@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch from 78b7004 to fd73e6aCompareOctober 17, 2025 18:49
* Ditch the `http_body.write()` back/front param that's no longer in the API.
* Make sure wasms get rebuilt when we change wsgi.py.
All endpoints now work properly when hit from a browser.
They were just pointed at the components that lacked wasiless.
Doing it more straightforwardly doesn't work, as the CI runner has no privs to check out internal repos, even from the same org.
Switch to a tag for a simple way of telling when the cache should be invalidated: the tag changes.

@posborneposborne left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes here all seem reasonable; I'll need to review the conversations and wasiless changes to see how we made the composition work, but would be happy to see this land to get things back to a working state.

@erikrose

erikrose commented Oct 20, 2025

Copy link
Copy Markdown
MemberAuthor

Thanks! Basically, we took the WIT imports living in component-py's output and had wasiless fulfill only those—minus what Viceroy would fulfill itself. Let me know if you have questions!

@erikrose
erikrose merged commit 22891f2 into mainOct 20, 2025
3 checks passed
@erikrose
erikrose deleted the get-wasiless-working-with-flask branch October 20, 2025 16:10
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@erikrose@posborne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Get Python apps working again after Viceroy WIT updates etc. - #10

Merged
erikrose merged 23 commits into
mainfrom
get-wasiless-working-with-flask
Oct 20, 2025
Merged

Get Python apps working again after Viceroy WIT updates etc.#10
erikrose merged 23 commits into
mainfrom
get-wasiless-working-with-flask

Conversation

@erikrose

@erikroseerikrose commented Oct 16, 2025

Copy link
Copy Markdown
Member

Both example apps now link, run, and pass tests happily. We do this by interposing wasiless, a null implementation of the WASI routines outside Viceroy's purview, which satisfies CPython's importing (and sometimes calling) of them: things like ttys and FSs.

The only caveat is you have to use the erik/python-sdk-2 branch of Viceroy, which increases the allowed number of memories to 2 to allow the wasiless component to fit. The CI job uses a tag on that branch.

Also…

  • Switch to self-hosted testrunners, because the GH-hosted ones will quit working in our org in a few days. Bonus: building Viceroy takes 25s instead of 2m.
  • Cache builds of Viceroy and other tools for speed, bringing a warm CI run to about 1m. We could cache further if we wanted.
  • Sync up with Viceroy's latest WIT files.
  • Support an env var to prefer a specific path to Viceroy.

erikroseand others added 14 commits October 8, 2025 10:41
This shouldn't matter, but it's one less thing to conflict.
…stubs.
Note both flask-app.wasm and wit-bottle.wasm have identical WIT (and thus imports), so one should link if the other does.
Current error:
```
% wac compose --dep fastly:wasiless=../wasiless/componentized.wasm --dep app:component=build/wit-bottle.wasm -o composed.wasm wrap_app_in_wasiless.wac
error: the encoding of the graph failed validation
Caused by:
type mismatch for import `wasi:filesystem/types@0.2.0`
type mismatch in instance export `input-stream`
resource types are not the same (ResourceId { globally_unique_id: 2, contextually_unique_id: 134 } vs. ResourceId { globally_unique_id: 2, contextually_unique_id: 6 }) (at offset 0x2916624)
```
…he imports of `wit-bottle.wasm`.
In other words, this "should work".
Specifically, revise the wac to not import anything that is provided by the Compute `service-imports` world. Those items should be provided directly by the host (Viceroy or similar), as then it will actually be functional.
Add in `poll`, as Python imports it but `service-imports` does not (so it's not provided to services by the host).
…bbcc9e92e43545224.
I don't know that it makes any difference, but now it matches wasiless'.
This solves the immediate `pollable` type mismatch when `wac`ing together a Python component.
It makes it easier for me to follow.
That means deleting it and referencing the `fastly:compute/service` world directly. It covers all the imports and exports we need.
Then use wasm-tools component new to transform to a component
for use with wac.
This illustrates the contrast in behavior between leaf and non-leaf WIT interfaces and positions us to move forward inch by inch.
As far as Viceroy is concerned, we need export only `http-incoming`.
…ink and run, culminating in a Python traceback.
Delegate to the wasiless repo for building the wasiless component.
@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch 2 times, most recently from 2dd32f4 to 186413dCompareOctober 16, 2025 21:37
@fastly-forge-auditor

Copy link
Copy Markdown

⚠️⚠️⚠️ Future executions of the workflow Python CI will be aborted starting in 12 days due to the usage of non-approved GitHub runner labels.
Offending label: [ubuntu-latest]


Please, contact Developer Platform at #ci-support if you need help using Forge runners

@fastly-forge-auditor

Copy link
Copy Markdown

⚠️⚠️⚠️ Future executions of the workflow Python CI will be aborted starting in 11 days due to the usage of non-approved GitHub runner labels.
Offending label: [ubuntu-latest]


Please, contact Developer Platform at #ci-support if you need help using Forge runners

@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch from 4909933 to 85e8fdbCompareOctober 17, 2025 15:44
@erikrose

erikrose commented Oct 17, 2025

Copy link
Copy Markdown
MemberAuthor

The problem is that wasiless can't be checked out as a submodule because it's an Internal repo. [Fixed.]

@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch from 78b7004 to fd73e6aCompareOctober 17, 2025 18:49
* Ditch the `http_body.write()` back/front param that's no longer in the API.
* Make sure wasms get rebuilt when we change wsgi.py.
All endpoints now work properly when hit from a browser.
They were just pointed at the components that lacked wasiless.
Doing it more straightforwardly doesn't work, as the CI runner has no privs to check out internal repos, even from the same org.
Switch to a tag for a simple way of telling when the cache should be invalidated: the tag changes.

@posborneposborne left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes here all seem reasonable; I'll need to review the conversations and wasiless changes to see how we made the composition work, but would be happy to see this land to get things back to a working state.

@erikrose

erikrose commented Oct 20, 2025

Copy link
Copy Markdown
MemberAuthor

Thanks! Basically, we took the WIT imports living in component-py's output and had wasiless fulfill only those—minus what Viceroy would fulfill itself. Let me know if you have questions!

@erikrose
erikrose merged commit 22891f2 into mainOct 20, 2025
3 checks passed
@erikrose
erikrose deleted the get-wasiless-working-with-flask branch October 20, 2025 16:10
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@erikrose@posborne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Get Python apps working again after Viceroy WIT updates etc. - #10

Merged
erikrose merged 23 commits into
mainfrom
get-wasiless-working-with-flask
Oct 20, 2025
Merged

Get Python apps working again after Viceroy WIT updates etc.#10
erikrose merged 23 commits into
mainfrom
get-wasiless-working-with-flask

Conversation

@erikrose

@erikroseerikrose commented Oct 16, 2025

Copy link
Copy Markdown
Member

Both example apps now link, run, and pass tests happily. We do this by interposing wasiless, a null implementation of the WASI routines outside Viceroy's purview, which satisfies CPython's importing (and sometimes calling) of them: things like ttys and FSs.

The only caveat is you have to use the erik/python-sdk-2 branch of Viceroy, which increases the allowed number of memories to 2 to allow the wasiless component to fit. The CI job uses a tag on that branch.

Also…

  • Switch to self-hosted testrunners, because the GH-hosted ones will quit working in our org in a few days. Bonus: building Viceroy takes 25s instead of 2m.
  • Cache builds of Viceroy and other tools for speed, bringing a warm CI run to about 1m. We could cache further if we wanted.
  • Sync up with Viceroy's latest WIT files.
  • Support an env var to prefer a specific path to Viceroy.

erikroseand others added 14 commits October 8, 2025 10:41
This shouldn't matter, but it's one less thing to conflict.
…stubs.
Note both flask-app.wasm and wit-bottle.wasm have identical WIT (and thus imports), so one should link if the other does.
Current error:
```
% wac compose --dep fastly:wasiless=../wasiless/componentized.wasm --dep app:component=build/wit-bottle.wasm -o composed.wasm wrap_app_in_wasiless.wac
error: the encoding of the graph failed validation
Caused by:
type mismatch for import `wasi:filesystem/types@0.2.0`
type mismatch in instance export `input-stream`
resource types are not the same (ResourceId { globally_unique_id: 2, contextually_unique_id: 134 } vs. ResourceId { globally_unique_id: 2, contextually_unique_id: 6 }) (at offset 0x2916624)
```
…he imports of `wit-bottle.wasm`.
In other words, this "should work".
Specifically, revise the wac to not import anything that is provided by the Compute `service-imports` world. Those items should be provided directly by the host (Viceroy or similar), as then it will actually be functional.
Add in `poll`, as Python imports it but `service-imports` does not (so it's not provided to services by the host).
…bbcc9e92e43545224.
I don't know that it makes any difference, but now it matches wasiless'.
This solves the immediate `pollable` type mismatch when `wac`ing together a Python component.
It makes it easier for me to follow.
That means deleting it and referencing the `fastly:compute/service` world directly. It covers all the imports and exports we need.
Then use wasm-tools component new to transform to a component
for use with wac.
This illustrates the contrast in behavior between leaf and non-leaf WIT interfaces and positions us to move forward inch by inch.
As far as Viceroy is concerned, we need export only `http-incoming`.
…ink and run, culminating in a Python traceback.
Delegate to the wasiless repo for building the wasiless component.
@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch 2 times, most recently from 2dd32f4 to 186413dCompareOctober 16, 2025 21:37
@fastly-forge-auditor

Copy link
Copy Markdown

⚠️⚠️⚠️ Future executions of the workflow Python CI will be aborted starting in 12 days due to the usage of non-approved GitHub runner labels.
Offending label: [ubuntu-latest]


Please, contact Developer Platform at #ci-support if you need help using Forge runners

@fastly-forge-auditor

Copy link
Copy Markdown

⚠️⚠️⚠️ Future executions of the workflow Python CI will be aborted starting in 11 days due to the usage of non-approved GitHub runner labels.
Offending label: [ubuntu-latest]


Please, contact Developer Platform at #ci-support if you need help using Forge runners

@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch from 4909933 to 85e8fdbCompareOctober 17, 2025 15:44
@erikrose

erikrose commented Oct 17, 2025

Copy link
Copy Markdown
MemberAuthor

The problem is that wasiless can't be checked out as a submodule because it's an Internal repo. [Fixed.]

@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch from 78b7004 to fd73e6aCompareOctober 17, 2025 18:49
* Ditch the `http_body.write()` back/front param that's no longer in the API.
* Make sure wasms get rebuilt when we change wsgi.py.
All endpoints now work properly when hit from a browser.
They were just pointed at the components that lacked wasiless.
Doing it more straightforwardly doesn't work, as the CI runner has no privs to check out internal repos, even from the same org.
Switch to a tag for a simple way of telling when the cache should be invalidated: the tag changes.

@posborneposborne left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes here all seem reasonable; I'll need to review the conversations and wasiless changes to see how we made the composition work, but would be happy to see this land to get things back to a working state.

@erikrose

erikrose commented Oct 20, 2025

Copy link
Copy Markdown
MemberAuthor

Thanks! Basically, we took the WIT imports living in component-py's output and had wasiless fulfill only those—minus what Viceroy would fulfill itself. Let me know if you have questions!

@erikrose
erikrose merged commit 22891f2 into mainOct 20, 2025
3 checks passed
@erikrose
erikrose deleted the get-wasiless-working-with-flask branch October 20, 2025 16:10
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@erikrose@posborne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Get Python apps working again after Viceroy WIT updates etc. - #10

Merged
erikrose merged 23 commits into
mainfrom
get-wasiless-working-with-flask
Oct 20, 2025
Merged

Get Python apps working again after Viceroy WIT updates etc.#10
erikrose merged 23 commits into
mainfrom
get-wasiless-working-with-flask

Conversation

@erikrose

@erikroseerikrose commented Oct 16, 2025

Copy link
Copy Markdown
Member

Both example apps now link, run, and pass tests happily. We do this by interposing wasiless, a null implementation of the WASI routines outside Viceroy's purview, which satisfies CPython's importing (and sometimes calling) of them: things like ttys and FSs.

The only caveat is you have to use the erik/python-sdk-2 branch of Viceroy, which increases the allowed number of memories to 2 to allow the wasiless component to fit. The CI job uses a tag on that branch.

Also…

  • Switch to self-hosted testrunners, because the GH-hosted ones will quit working in our org in a few days. Bonus: building Viceroy takes 25s instead of 2m.
  • Cache builds of Viceroy and other tools for speed, bringing a warm CI run to about 1m. We could cache further if we wanted.
  • Sync up with Viceroy's latest WIT files.
  • Support an env var to prefer a specific path to Viceroy.

erikroseand others added 14 commits October 8, 2025 10:41
This shouldn't matter, but it's one less thing to conflict.
…stubs.
Note both flask-app.wasm and wit-bottle.wasm have identical WIT (and thus imports), so one should link if the other does.
Current error:
```
% wac compose --dep fastly:wasiless=../wasiless/componentized.wasm --dep app:component=build/wit-bottle.wasm -o composed.wasm wrap_app_in_wasiless.wac
error: the encoding of the graph failed validation
Caused by:
type mismatch for import `wasi:filesystem/types@0.2.0`
type mismatch in instance export `input-stream`
resource types are not the same (ResourceId { globally_unique_id: 2, contextually_unique_id: 134 } vs. ResourceId { globally_unique_id: 2, contextually_unique_id: 6 }) (at offset 0x2916624)
```
…he imports of `wit-bottle.wasm`.
In other words, this "should work".
Specifically, revise the wac to not import anything that is provided by the Compute `service-imports` world. Those items should be provided directly by the host (Viceroy or similar), as then it will actually be functional.
Add in `poll`, as Python imports it but `service-imports` does not (so it's not provided to services by the host).
…bbcc9e92e43545224.
I don't know that it makes any difference, but now it matches wasiless'.
This solves the immediate `pollable` type mismatch when `wac`ing together a Python component.
It makes it easier for me to follow.
That means deleting it and referencing the `fastly:compute/service` world directly. It covers all the imports and exports we need.
Then use wasm-tools component new to transform to a component
for use with wac.
This illustrates the contrast in behavior between leaf and non-leaf WIT interfaces and positions us to move forward inch by inch.
As far as Viceroy is concerned, we need export only `http-incoming`.
…ink and run, culminating in a Python traceback.
Delegate to the wasiless repo for building the wasiless component.
@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch 2 times, most recently from 2dd32f4 to 186413dCompareOctober 16, 2025 21:37
@fastly-forge-auditor

Copy link
Copy Markdown

⚠️⚠️⚠️ Future executions of the workflow Python CI will be aborted starting in 12 days due to the usage of non-approved GitHub runner labels.
Offending label: [ubuntu-latest]


Please, contact Developer Platform at #ci-support if you need help using Forge runners

@fastly-forge-auditor

Copy link
Copy Markdown

⚠️⚠️⚠️ Future executions of the workflow Python CI will be aborted starting in 11 days due to the usage of non-approved GitHub runner labels.
Offending label: [ubuntu-latest]


Please, contact Developer Platform at #ci-support if you need help using Forge runners

@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch from 4909933 to 85e8fdbCompareOctober 17, 2025 15:44
@erikrose

erikrose commented Oct 17, 2025

Copy link
Copy Markdown
MemberAuthor

The problem is that wasiless can't be checked out as a submodule because it's an Internal repo. [Fixed.]

@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch from 78b7004 to fd73e6aCompareOctober 17, 2025 18:49
* Ditch the `http_body.write()` back/front param that's no longer in the API.
* Make sure wasms get rebuilt when we change wsgi.py.
All endpoints now work properly when hit from a browser.
They were just pointed at the components that lacked wasiless.
Doing it more straightforwardly doesn't work, as the CI runner has no privs to check out internal repos, even from the same org.
Switch to a tag for a simple way of telling when the cache should be invalidated: the tag changes.

@posborneposborne left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes here all seem reasonable; I'll need to review the conversations and wasiless changes to see how we made the composition work, but would be happy to see this land to get things back to a working state.

@erikrose

erikrose commented Oct 20, 2025

Copy link
Copy Markdown
MemberAuthor

Thanks! Basically, we took the WIT imports living in component-py's output and had wasiless fulfill only those—minus what Viceroy would fulfill itself. Let me know if you have questions!

@erikrose
erikrose merged commit 22891f2 into mainOct 20, 2025
3 checks passed
@erikrose
erikrose deleted the get-wasiless-working-with-flask branch October 20, 2025 16:10
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@erikrose@posborne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Get Python apps working again after Viceroy WIT updates etc. - #10

Merged
erikrose merged 23 commits into
mainfrom
get-wasiless-working-with-flask
Oct 20, 2025
Merged

Get Python apps working again after Viceroy WIT updates etc.#10
erikrose merged 23 commits into
mainfrom
get-wasiless-working-with-flask

Conversation

@erikrose

@erikroseerikrose commented Oct 16, 2025

Copy link
Copy Markdown
Member

Both example apps now link, run, and pass tests happily. We do this by interposing wasiless, a null implementation of the WASI routines outside Viceroy's purview, which satisfies CPython's importing (and sometimes calling) of them: things like ttys and FSs.

The only caveat is you have to use the erik/python-sdk-2 branch of Viceroy, which increases the allowed number of memories to 2 to allow the wasiless component to fit. The CI job uses a tag on that branch.

Also…

  • Switch to self-hosted testrunners, because the GH-hosted ones will quit working in our org in a few days. Bonus: building Viceroy takes 25s instead of 2m.
  • Cache builds of Viceroy and other tools for speed, bringing a warm CI run to about 1m. We could cache further if we wanted.
  • Sync up with Viceroy's latest WIT files.
  • Support an env var to prefer a specific path to Viceroy.

erikroseand others added 14 commits October 8, 2025 10:41
This shouldn't matter, but it's one less thing to conflict.
…stubs.
Note both flask-app.wasm and wit-bottle.wasm have identical WIT (and thus imports), so one should link if the other does.
Current error:
```
% wac compose --dep fastly:wasiless=../wasiless/componentized.wasm --dep app:component=build/wit-bottle.wasm -o composed.wasm wrap_app_in_wasiless.wac
error: the encoding of the graph failed validation
Caused by:
type mismatch for import `wasi:filesystem/types@0.2.0`
type mismatch in instance export `input-stream`
resource types are not the same (ResourceId { globally_unique_id: 2, contextually_unique_id: 134 } vs. ResourceId { globally_unique_id: 2, contextually_unique_id: 6 }) (at offset 0x2916624)
```
…he imports of `wit-bottle.wasm`.
In other words, this "should work".
Specifically, revise the wac to not import anything that is provided by the Compute `service-imports` world. Those items should be provided directly by the host (Viceroy or similar), as then it will actually be functional.
Add in `poll`, as Python imports it but `service-imports` does not (so it's not provided to services by the host).
…bbcc9e92e43545224.
I don't know that it makes any difference, but now it matches wasiless'.
This solves the immediate `pollable` type mismatch when `wac`ing together a Python component.
It makes it easier for me to follow.
That means deleting it and referencing the `fastly:compute/service` world directly. It covers all the imports and exports we need.
Then use wasm-tools component new to transform to a component
for use with wac.
This illustrates the contrast in behavior between leaf and non-leaf WIT interfaces and positions us to move forward inch by inch.
As far as Viceroy is concerned, we need export only `http-incoming`.
…ink and run, culminating in a Python traceback.
Delegate to the wasiless repo for building the wasiless component.
@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch 2 times, most recently from 2dd32f4 to 186413dCompareOctober 16, 2025 21:37
@fastly-forge-auditor

Copy link
Copy Markdown

⚠️⚠️⚠️ Future executions of the workflow Python CI will be aborted starting in 12 days due to the usage of non-approved GitHub runner labels.
Offending label: [ubuntu-latest]


Please, contact Developer Platform at #ci-support if you need help using Forge runners

@fastly-forge-auditor

Copy link
Copy Markdown

⚠️⚠️⚠️ Future executions of the workflow Python CI will be aborted starting in 11 days due to the usage of non-approved GitHub runner labels.
Offending label: [ubuntu-latest]


Please, contact Developer Platform at #ci-support if you need help using Forge runners

@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch from 4909933 to 85e8fdbCompareOctober 17, 2025 15:44
@erikrose

erikrose commented Oct 17, 2025

Copy link
Copy Markdown
MemberAuthor

The problem is that wasiless can't be checked out as a submodule because it's an Internal repo. [Fixed.]

@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch from 78b7004 to fd73e6aCompareOctober 17, 2025 18:49
* Ditch the `http_body.write()` back/front param that's no longer in the API.
* Make sure wasms get rebuilt when we change wsgi.py.
All endpoints now work properly when hit from a browser.
They were just pointed at the components that lacked wasiless.
Doing it more straightforwardly doesn't work, as the CI runner has no privs to check out internal repos, even from the same org.
Switch to a tag for a simple way of telling when the cache should be invalidated: the tag changes.

@posborneposborne left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes here all seem reasonable; I'll need to review the conversations and wasiless changes to see how we made the composition work, but would be happy to see this land to get things back to a working state.

@erikrose

erikrose commented Oct 20, 2025

Copy link
Copy Markdown
MemberAuthor

Thanks! Basically, we took the WIT imports living in component-py's output and had wasiless fulfill only those—minus what Viceroy would fulfill itself. Let me know if you have questions!

@erikrose
erikrose merged commit 22891f2 into mainOct 20, 2025
3 checks passed
@erikrose
erikrose deleted the get-wasiless-working-with-flask branch October 20, 2025 16:10
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@erikrose@posborne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Get Python apps working again after Viceroy WIT updates etc. - #10

Merged
erikrose merged 23 commits into
mainfrom
get-wasiless-working-with-flask
Oct 20, 2025
Merged

Get Python apps working again after Viceroy WIT updates etc.#10
erikrose merged 23 commits into
mainfrom
get-wasiless-working-with-flask

Conversation

@erikrose

@erikroseerikrose commented Oct 16, 2025

Copy link
Copy Markdown
Member

Both example apps now link, run, and pass tests happily. We do this by interposing wasiless, a null implementation of the WASI routines outside Viceroy's purview, which satisfies CPython's importing (and sometimes calling) of them: things like ttys and FSs.

The only caveat is you have to use the erik/python-sdk-2 branch of Viceroy, which increases the allowed number of memories to 2 to allow the wasiless component to fit. The CI job uses a tag on that branch.

Also…

  • Switch to self-hosted testrunners, because the GH-hosted ones will quit working in our org in a few days. Bonus: building Viceroy takes 25s instead of 2m.
  • Cache builds of Viceroy and other tools for speed, bringing a warm CI run to about 1m. We could cache further if we wanted.
  • Sync up with Viceroy's latest WIT files.
  • Support an env var to prefer a specific path to Viceroy.

erikroseand others added 14 commits October 8, 2025 10:41
This shouldn't matter, but it's one less thing to conflict.
…stubs.
Note both flask-app.wasm and wit-bottle.wasm have identical WIT (and thus imports), so one should link if the other does.
Current error:
```
% wac compose --dep fastly:wasiless=../wasiless/componentized.wasm --dep app:component=build/wit-bottle.wasm -o composed.wasm wrap_app_in_wasiless.wac
error: the encoding of the graph failed validation
Caused by:
type mismatch for import `wasi:filesystem/types@0.2.0`
type mismatch in instance export `input-stream`
resource types are not the same (ResourceId { globally_unique_id: 2, contextually_unique_id: 134 } vs. ResourceId { globally_unique_id: 2, contextually_unique_id: 6 }) (at offset 0x2916624)
```
…he imports of `wit-bottle.wasm`.
In other words, this "should work".
Specifically, revise the wac to not import anything that is provided by the Compute `service-imports` world. Those items should be provided directly by the host (Viceroy or similar), as then it will actually be functional.
Add in `poll`, as Python imports it but `service-imports` does not (so it's not provided to services by the host).
…bbcc9e92e43545224.
I don't know that it makes any difference, but now it matches wasiless'.
This solves the immediate `pollable` type mismatch when `wac`ing together a Python component.
It makes it easier for me to follow.
That means deleting it and referencing the `fastly:compute/service` world directly. It covers all the imports and exports we need.
Then use wasm-tools component new to transform to a component
for use with wac.
This illustrates the contrast in behavior between leaf and non-leaf WIT interfaces and positions us to move forward inch by inch.
As far as Viceroy is concerned, we need export only `http-incoming`.
…ink and run, culminating in a Python traceback.
Delegate to the wasiless repo for building the wasiless component.
@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch 2 times, most recently from 2dd32f4 to 186413dCompareOctober 16, 2025 21:37
@fastly-forge-auditor

Copy link
Copy Markdown

⚠️⚠️⚠️ Future executions of the workflow Python CI will be aborted starting in 12 days due to the usage of non-approved GitHub runner labels.
Offending label: [ubuntu-latest]


Please, contact Developer Platform at #ci-support if you need help using Forge runners

@fastly-forge-auditor

Copy link
Copy Markdown

⚠️⚠️⚠️ Future executions of the workflow Python CI will be aborted starting in 11 days due to the usage of non-approved GitHub runner labels.
Offending label: [ubuntu-latest]


Please, contact Developer Platform at #ci-support if you need help using Forge runners

@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch from 4909933 to 85e8fdbCompareOctober 17, 2025 15:44
@erikrose

erikrose commented Oct 17, 2025

Copy link
Copy Markdown
MemberAuthor

The problem is that wasiless can't be checked out as a submodule because it's an Internal repo. [Fixed.]

@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch from 78b7004 to fd73e6aCompareOctober 17, 2025 18:49
* Ditch the `http_body.write()` back/front param that's no longer in the API.
* Make sure wasms get rebuilt when we change wsgi.py.
All endpoints now work properly when hit from a browser.
They were just pointed at the components that lacked wasiless.
Doing it more straightforwardly doesn't work, as the CI runner has no privs to check out internal repos, even from the same org.
Switch to a tag for a simple way of telling when the cache should be invalidated: the tag changes.

@posborneposborne left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes here all seem reasonable; I'll need to review the conversations and wasiless changes to see how we made the composition work, but would be happy to see this land to get things back to a working state.

@erikrose

erikrose commented Oct 20, 2025

Copy link
Copy Markdown
MemberAuthor

Thanks! Basically, we took the WIT imports living in component-py's output and had wasiless fulfill only those—minus what Viceroy would fulfill itself. Let me know if you have questions!

@erikrose
erikrose merged commit 22891f2 into mainOct 20, 2025
3 checks passed
@erikrose
erikrose deleted the get-wasiless-working-with-flask branch October 20, 2025 16:10
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@erikrose@posborne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Get Python apps working again after Viceroy WIT updates etc. - #10

Merged
erikrose merged 23 commits into
mainfrom
get-wasiless-working-with-flask
Oct 20, 2025
Merged

Get Python apps working again after Viceroy WIT updates etc.#10
erikrose merged 23 commits into
mainfrom
get-wasiless-working-with-flask

Conversation

@erikrose

@erikroseerikrose commented Oct 16, 2025

Copy link
Copy Markdown
Member

Both example apps now link, run, and pass tests happily. We do this by interposing wasiless, a null implementation of the WASI routines outside Viceroy's purview, which satisfies CPython's importing (and sometimes calling) of them: things like ttys and FSs.

The only caveat is you have to use the erik/python-sdk-2 branch of Viceroy, which increases the allowed number of memories to 2 to allow the wasiless component to fit. The CI job uses a tag on that branch.

Also…

  • Switch to self-hosted testrunners, because the GH-hosted ones will quit working in our org in a few days. Bonus: building Viceroy takes 25s instead of 2m.
  • Cache builds of Viceroy and other tools for speed, bringing a warm CI run to about 1m. We could cache further if we wanted.
  • Sync up with Viceroy's latest WIT files.
  • Support an env var to prefer a specific path to Viceroy.

erikroseand others added 14 commits October 8, 2025 10:41
This shouldn't matter, but it's one less thing to conflict.
…stubs.
Note both flask-app.wasm and wit-bottle.wasm have identical WIT (and thus imports), so one should link if the other does.
Current error:
```
% wac compose --dep fastly:wasiless=../wasiless/componentized.wasm --dep app:component=build/wit-bottle.wasm -o composed.wasm wrap_app_in_wasiless.wac
error: the encoding of the graph failed validation
Caused by:
type mismatch for import `wasi:filesystem/types@0.2.0`
type mismatch in instance export `input-stream`
resource types are not the same (ResourceId { globally_unique_id: 2, contextually_unique_id: 134 } vs. ResourceId { globally_unique_id: 2, contextually_unique_id: 6 }) (at offset 0x2916624)
```
…he imports of `wit-bottle.wasm`.
In other words, this "should work".
Specifically, revise the wac to not import anything that is provided by the Compute `service-imports` world. Those items should be provided directly by the host (Viceroy or similar), as then it will actually be functional.
Add in `poll`, as Python imports it but `service-imports` does not (so it's not provided to services by the host).
…bbcc9e92e43545224.
I don't know that it makes any difference, but now it matches wasiless'.
This solves the immediate `pollable` type mismatch when `wac`ing together a Python component.
It makes it easier for me to follow.
That means deleting it and referencing the `fastly:compute/service` world directly. It covers all the imports and exports we need.
Then use wasm-tools component new to transform to a component
for use with wac.
This illustrates the contrast in behavior between leaf and non-leaf WIT interfaces and positions us to move forward inch by inch.
As far as Viceroy is concerned, we need export only `http-incoming`.
…ink and run, culminating in a Python traceback.
Delegate to the wasiless repo for building the wasiless component.
@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch 2 times, most recently from 2dd32f4 to 186413dCompareOctober 16, 2025 21:37
@fastly-forge-auditor

Copy link
Copy Markdown

⚠️⚠️⚠️ Future executions of the workflow Python CI will be aborted starting in 12 days due to the usage of non-approved GitHub runner labels.
Offending label: [ubuntu-latest]


Please, contact Developer Platform at #ci-support if you need help using Forge runners

@fastly-forge-auditor

Copy link
Copy Markdown

⚠️⚠️⚠️ Future executions of the workflow Python CI will be aborted starting in 11 days due to the usage of non-approved GitHub runner labels.
Offending label: [ubuntu-latest]


Please, contact Developer Platform at #ci-support if you need help using Forge runners

@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch from 4909933 to 85e8fdbCompareOctober 17, 2025 15:44
@erikrose

erikrose commented Oct 17, 2025

Copy link
Copy Markdown
MemberAuthor

The problem is that wasiless can't be checked out as a submodule because it's an Internal repo. [Fixed.]

@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch from 78b7004 to fd73e6aCompareOctober 17, 2025 18:49
* Ditch the `http_body.write()` back/front param that's no longer in the API.
* Make sure wasms get rebuilt when we change wsgi.py.
All endpoints now work properly when hit from a browser.
They were just pointed at the components that lacked wasiless.
Doing it more straightforwardly doesn't work, as the CI runner has no privs to check out internal repos, even from the same org.
Switch to a tag for a simple way of telling when the cache should be invalidated: the tag changes.

@posborneposborne left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes here all seem reasonable; I'll need to review the conversations and wasiless changes to see how we made the composition work, but would be happy to see this land to get things back to a working state.

@erikrose

erikrose commented Oct 20, 2025

Copy link
Copy Markdown
MemberAuthor

Thanks! Basically, we took the WIT imports living in component-py's output and had wasiless fulfill only those—minus what Viceroy would fulfill itself. Let me know if you have questions!

@erikrose
erikrose merged commit 22891f2 into mainOct 20, 2025
3 checks passed
@erikrose
erikrose deleted the get-wasiless-working-with-flask branch October 20, 2025 16:10
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@erikrose@posborne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Get Python apps working again after Viceroy WIT updates etc. - #10

Merged
erikrose merged 23 commits into
mainfrom
get-wasiless-working-with-flask
Oct 20, 2025
Merged

Get Python apps working again after Viceroy WIT updates etc.#10
erikrose merged 23 commits into
mainfrom
get-wasiless-working-with-flask

Conversation

@erikrose

@erikroseerikrose commented Oct 16, 2025

Copy link
Copy Markdown
Member

Both example apps now link, run, and pass tests happily. We do this by interposing wasiless, a null implementation of the WASI routines outside Viceroy's purview, which satisfies CPython's importing (and sometimes calling) of them: things like ttys and FSs.

The only caveat is you have to use the erik/python-sdk-2 branch of Viceroy, which increases the allowed number of memories to 2 to allow the wasiless component to fit. The CI job uses a tag on that branch.

Also…

  • Switch to self-hosted testrunners, because the GH-hosted ones will quit working in our org in a few days. Bonus: building Viceroy takes 25s instead of 2m.
  • Cache builds of Viceroy and other tools for speed, bringing a warm CI run to about 1m. We could cache further if we wanted.
  • Sync up with Viceroy's latest WIT files.
  • Support an env var to prefer a specific path to Viceroy.

erikroseand others added 14 commits October 8, 2025 10:41
This shouldn't matter, but it's one less thing to conflict.
…stubs.
Note both flask-app.wasm and wit-bottle.wasm have identical WIT (and thus imports), so one should link if the other does.
Current error:
```
% wac compose --dep fastly:wasiless=../wasiless/componentized.wasm --dep app:component=build/wit-bottle.wasm -o composed.wasm wrap_app_in_wasiless.wac
error: the encoding of the graph failed validation
Caused by:
type mismatch for import `wasi:filesystem/types@0.2.0`
type mismatch in instance export `input-stream`
resource types are not the same (ResourceId { globally_unique_id: 2, contextually_unique_id: 134 } vs. ResourceId { globally_unique_id: 2, contextually_unique_id: 6 }) (at offset 0x2916624)
```
…he imports of `wit-bottle.wasm`.
In other words, this "should work".
Specifically, revise the wac to not import anything that is provided by the Compute `service-imports` world. Those items should be provided directly by the host (Viceroy or similar), as then it will actually be functional.
Add in `poll`, as Python imports it but `service-imports` does not (so it's not provided to services by the host).
…bbcc9e92e43545224.
I don't know that it makes any difference, but now it matches wasiless'.
This solves the immediate `pollable` type mismatch when `wac`ing together a Python component.
It makes it easier for me to follow.
That means deleting it and referencing the `fastly:compute/service` world directly. It covers all the imports and exports we need.
Then use wasm-tools component new to transform to a component
for use with wac.
This illustrates the contrast in behavior between leaf and non-leaf WIT interfaces and positions us to move forward inch by inch.
As far as Viceroy is concerned, we need export only `http-incoming`.
…ink and run, culminating in a Python traceback.
Delegate to the wasiless repo for building the wasiless component.
@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch 2 times, most recently from 2dd32f4 to 186413dCompareOctober 16, 2025 21:37
@fastly-forge-auditor

Copy link
Copy Markdown

⚠️⚠️⚠️ Future executions of the workflow Python CI will be aborted starting in 12 days due to the usage of non-approved GitHub runner labels.
Offending label: [ubuntu-latest]


Please, contact Developer Platform at #ci-support if you need help using Forge runners

@fastly-forge-auditor

Copy link
Copy Markdown

⚠️⚠️⚠️ Future executions of the workflow Python CI will be aborted starting in 11 days due to the usage of non-approved GitHub runner labels.
Offending label: [ubuntu-latest]


Please, contact Developer Platform at #ci-support if you need help using Forge runners

@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch from 4909933 to 85e8fdbCompareOctober 17, 2025 15:44
@erikrose

erikrose commented Oct 17, 2025

Copy link
Copy Markdown
MemberAuthor

The problem is that wasiless can't be checked out as a submodule because it's an Internal repo. [Fixed.]

@erikrose
erikroseforce-pushed the get-wasiless-working-with-flask branch from 78b7004 to fd73e6aCompareOctober 17, 2025 18:49
* Ditch the `http_body.write()` back/front param that's no longer in the API.
* Make sure wasms get rebuilt when we change wsgi.py.
All endpoints now work properly when hit from a browser.
They were just pointed at the components that lacked wasiless.
Doing it more straightforwardly doesn't work, as the CI runner has no privs to check out internal repos, even from the same org.
Switch to a tag for a simple way of telling when the cache should be invalidated: the tag changes.

@posborneposborne left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes here all seem reasonable; I'll need to review the conversations and wasiless changes to see how we made the composition work, but would be happy to see this land to get things back to a working state.

@erikrose

erikrose commented Oct 20, 2025

Copy link
Copy Markdown
MemberAuthor

Thanks! Basically, we took the WIT imports living in component-py's output and had wasiless fulfill only those—minus what Viceroy would fulfill itself. Let me know if you have questions!

@erikrose
erikrose merged commit 22891f2 into mainOct 20, 2025
3 checks passed
@erikrose
erikrose deleted the get-wasiless-working-with-flask branch October 20, 2025 16:10
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@erikrose@posborne