Skip to content

Commit 0665470

Browse files
committed
Added File System things
1 parent 7cf1b25 commit 0665470

File tree

1 file changed

+102
-1
lines changed

1 file changed

+102
-1
lines changed

docs/user-guide/faq.md

+102-1
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ For various reasons previously discussed at length, we decided to remove our `la
190190

191191
We were not super proud of users trusting that channel coming back with suddenly broken projects so we now [release only official versions](https://github.com/pyscript/pyscript/releases) everyone can pin-point in time.
192192

193-
We are also developing behind the scene through *npm* to be able to test in the wild breaking changes and what's not and it's no secret that *CDNs* could also deliver our "*canary*" or "*development*" channel so that we're better off telling you exactly which links one should use to have the latest, whenever latest lands on the *CDN* which is usually within 24 hours from the last *npm* version change.
193+
We are also developing behind the scene through *npm* to be able to test in the wild breaking changes and whatnot and it's no secret that *CDNs* could also deliver our "*canary*" or "*development*" channel so that we're better off telling you exactly which links one should use to have the latest, whenever latest lands on the *CDN* which is usually within 24 hours from the last *npm* version change.
194194

195195
We still **do not guarantee any stability** around this channel so be aware this is never a good idea to use in production, documentation might lack behind landed changes, APIs might break or change too, and so on.
196196

@@ -429,3 +429,104 @@ Once archived as `.zip` or as `.tar.gz` in a way that contains the *my_module* f
429429
```
430430

431431
Please **note** the `./*` convention, through a `.zip` or `.tar.gz` source, where the target folder with a star `*` will contain anything present in the source archive, in this example the whole *my_module* folder.
432+
433+
### File System
434+
435+
The first thing to understand about *PyScript* File System operations is that each interpreter provides *its own* *Virtual File System* that works **only in memory**.
436+
437+
!!! Note
438+
439+
We don't have yet a way to provide a shared, user's browser persistent, File System, so that any time we load or store and then read files we're doing that through the *RAM* and the current session: nothing is shared, nothing is stored, nothing persists!
440+
441+
#### Read/Write Content
442+
443+
The easiest way to add content to the virtual *FS* is by using native *Python* files operations:
444+
445+
```python title="Writing to a text file"
446+
with open("./test.txt", "w") as dest:
447+
dest.write("hello vFS")
448+
dest.close()
449+
450+
# read the written content
451+
source = open("./test.txt", "r")
452+
print(source.read())
453+
source.close()
454+
```
455+
456+
Combined with our `pyscript.fetch` utility, it's also possible to store from the web more complex data.
457+
458+
```python title="Writing file as binary"
459+
# assume an `async` attribute / execution
460+
from pyscript import fetch, window
461+
462+
href = window.location.href
463+
464+
with open("./page.html", "wb") as dest:
465+
dest.write(await fetch(href).bytearray())
466+
dest.close()
467+
468+
# read the current HTML page
469+
source = open("./page.html", "r")
470+
print(source.read())
471+
source.close()
472+
```
473+
474+
#### Upload Content
475+
476+
Through the DOM API it's possible to also upload a file and store it into the virtual *FS*.
477+
478+
The following example is just one of the ways one can do that, but it's a pretty simple one and based on the very same code and logic already seen in the previous paragraph:
479+
480+
```html title="Upload file into vFS"
481+
<input type="file">
482+
<script type="mpy">
483+
from pyscript import document, fetch, window
484+
485+
async def on_change(event):
486+
# per each file
487+
for file in input.files:
488+
# create a temporary URL
489+
tmp = window.URL.createObjectURL(file)
490+
# fetch and save its content somewhere
491+
with open(f"./{file.name}", "wb") as dest:
492+
dest.write(await fetch(tmp).bytearray())
493+
dest.close()
494+
# revoke the tmp URL
495+
window.URL.revokeObjectURL(tmp)
496+
497+
input = document.querySelector("input[type=file]")
498+
input.onchange = on_change
499+
</script>
500+
```
501+
502+
#### Download Content
503+
504+
Once a file is present in the virtual File System, it's always possible to create a temporary link which goal is to download such file:
505+
506+
```python title="Download file from vFS"
507+
def download_file(path, mime_type):
508+
from pyscript import document, ffi, window
509+
import os
510+
name = os.path.basename(path)
511+
with open(path, "rb") as source:
512+
data = source.read()
513+
514+
# this is Pyodide specific
515+
buffer = window.Uint8Array.from_(data)
516+
details = ffi.to_js({"type": mime_type})
517+
518+
# this is JS specific
519+
file = window.File.new([buffer], name, details)
520+
tmp = window.URL.createObjectURL(file)
521+
dest = document.createElement("a")
522+
dest.setAttribute("download", name)
523+
dest.setAttribute("href", tmp)
524+
dest.click()
525+
526+
# here a timeout to window.URL.revokeObjectURL(tmp)
527+
# should keep the memory clear for the session
528+
```
529+
530+
!!! warning
531+
532+
The presented utility works only on *Pyodide* at the moment, as there is no `from_` or `assign` convention in *MicroPython*. Once this is fixed or a better example is discovered the example will be updated too so that all of them should work in both interpreters.

0 commit comments

Comments
 (0)