-
Notifications
You must be signed in to change notification settings - Fork 5
Pyodide unzip/untar abilities + MicroPython unzip #84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
1a99647
to
6f283ec
Compare
This would be really helpful. Would be awesome if it worked on MicroPython too (asking for a friend). 😉 |
@ntoll based on lazy loaded zip.js library, it is now possible to un-archive also in MicroPython. My only thoughts around this are:
My quick answers to myself:
|
2c8472c
to
938e378
Compare
@WebReflection this is great. When I mentioned this feature to folks working on Invent they simply said, "oh yes please". Given MicroPython has I agree with your concerns about "offline" or isolated dependencies. If stuff is built into MicroPython I think we may be in a better place WRT this aspect of the work. |
About offline we still have the TOML parser that is lazy and requires a valid URL to point at ... I am thinking more and more to improve the dist packaging of this module exactly the same we did with PyScript as that would work out of the box for anything 3rd party we'd like to lazy load. This shouldn't take a lot of effort and things should be easier to implement in the near to next future. |
after a discussion we said that |
We do actually have support for reading uncompressed |
it's rather a way to simplify both hosting and config instructions: <!-- before -->
<py-config>
[files]
"./a/b.py" = "./dest/b.py"
"./a/b/c.py" = "./dest/b/c.py"
"./a/d.json" = "./dest/d.json"
"./a/b/x/y/z.py" = "./dest/b/x/y/z.py"
</py-config>
<!-- after -->
<py-config>
[files]
"./thing.zip" = "./dest/*"
</py-config>
I believe we don't want to confuse users about what is a valid zip and what isn't for MicroPython so unless the |
6c9e40b
to
a56d6e1
Compare
@dpgeorge I am really having hard time making utarfile working ... I import it correctly and everything is fine, but I always get errors ... I've tried to create the file with default
then I've used just # the "./_.tar.gz" file is a valid tar file Pyodide can handle with ease
# the extractDir is `./packages/` in my smoke test ... nothing works
import os
import utarfile
tar = utarfile.TarFile("./_.tar.gz")
# this loop breaks right away no matter what's in it
for f in tar:
name = f'${extractDir}{f.name[2:]}'
if f.type == utarfile.DIRTYPE:
if f.name != './':
os.mkdir(name.strip('/'))
else:
sub_file = tar.extractfile(f)
with open(name, "wb") as dest:
copyfileobj(sub_file, dest)
dest.close()
tar.close()
os.remove('./_.tar.gz') |
|
Indeed you'll need to do the decompression explicitly. Eg: import sys
import gzip
import tarfile
file = tarfile.TarFile(fileobj=gzip.GzipFile(fileobj=open(sys.argv[1], "rb")))
for elem in file:
print(elem.name) That works in both CPython and MicroPython (although in older version of MicroPython you need to use |
Yeah, |
awesome folks, I'll give it a try in some boring free time while on vacation 🙏 |
@dpgeorge tarfile not available out of the box but either tarfile or utarfile still give me errors: tar = utarfile.TarFile(fileobj=gzip.GzipFile(fileobj=open("./_.tar.gz","rb")))
for f in tar:
print(f.name) I think luike there's eomthing obvious I am missing ... error |
You are using an old version of Please try with the latest MicroPython wasm from here: micropython/micropython#13583 |
@dpgeorge tried latest (literally 2 minutes ago and build) ... the error is now different but still erroring:
I think I might wait for your latest PR to land and then take it from there with this untar-ability ... there is a chance I am doing something wrong but I want to be sure latest is latest. |
@WebReflection are you using What version does it give you when you run |
is that wrong? 🤔 I just rebased and run |
That's correct. But now that I try it out myself, I realise that I have not frozen Please try the latest build on that PR. You should get something like this:
(You may get a different version string, but still the hash of |
Hi folks, Things went quiet here. Just wondering what the current status of progress is..? (Asking for a friend 😉 ) |
@ntoll I am waiting for latest release on npm of MicroPython to finalize this MR (currently broken in there) and more ... if this happen soon with promise fixes in we can release tomorrow with latest greatest including this MR (as long as I manage to make it work on MicroPython) ... otherwise let me know if we should ship this half-backed on MicroPython side, no strong opinion here. edit reason it's on hold: #84 (comment) |
As far as I'm aware, the latest npm release of MicroPython should work for this untar case. |
I think I've fully missed this notification as I was in Boston micropython/micropython#13583 (comment) (actually I was not ... I just missed that!) I will then try again with latest and see where it goes from there, thank you! (and I'll keep you posted if something ain't right) |
I have just made another release which should also fix the thenable issue: https://www.npmjs.com/package/@micropython/micropython-webassembly-pyscript/v/1.22.0-269 |
@dpgeorge we're here ... everything broken now pyscript/pyscript#2001 (comment) |
@dpgeorge never mind, I can workaround that, I have Wasmoon shim that works out of just FS, we're good (but I really would like to have all Emscripten VFS utilities exposed not behind a |
The PATH/PATH_FS issue is fixed in the latest version: https://www.npmjs.com/package/@micropython/micropython-webassembly-pyscript/v/1.22.0-272 |
@dpgeorge I am almost there but having headaches I don't understand ... so ... const TMP = './_.tar.gz';
writeFile(fs, TMP, buffer);
interpreter.runPython(`
import os, gzip, tarfile
tar = tarfile.TarFile(fileobj=gzip.GzipFile(fileobj=open("${TMP}", "rb")))
for f in tar:
name = f"${extractDir}{f.name[2:]}"
if f.type == tarfile.DIRTYPE:
if f.name != "./":
os.mkdir(name.strip("/"))
else:
source = tar.extractfile(f)
with open(name, "wb") as dest:
dest.write(source.read())
dest.close()
tar.close()
os.remove("${TMP}")
`); This code works 🥳 ... meaning within that code I can then read every single written file and it's just fine. On the browser though ... <script type="micropython" config="pyodide.toml" worker>
from polyscript import xworker
f = open("./package/micropython.html", "r")
lines = f.readlines()
xworker.window.document.documentElement.classList.add(
lines[0] == "<!DOCTYPE html>\n"
)
</script> The Please note everything is fine if I unzip instead but the import os
print(os.listdir()) # the package is there
print(os.listdir("package")) # the index.html is there Do you have any idea what could possibly go wrong? I feel so close yet so far from shipping this |
@dpgeorge OK, this is awkward ... I have now MicroPython working with |
@dpgeorge I am an idiot ... I am going to fix this ASAP, it was me messing around with the files, apologies for all the pings ... I think I am really close to fix this! |
In this Discrod conversation a user asked to be able to provide a single
.zip
file (or.tar.gz
or other formats) to be easily extracted into a generic destination folder.As pyodide provides a way to do so we've exchanged a bit of ideas so that explicitly targeting that
.zip
file as./destination/*
, where/*
as end of the url is the trigger and the recognized archive extension completes it, I've explored that possibility and to me this looks like a no-brainer.About MicroPython (or others)
This feature requires an interpreter able to deal with these extensions in a way that complex structures with both folders and files, not just compressed single entry, can be represented in the file system so that right now (in this MR) this is available on Pyodide only.
@ntoll @fpliger @JeffersGlass thoughts? I'd be happy to move this first bit forward, if the contract is clear/approved:
That's it, that's the contract, it's explicit in the config and it understands via both extension and
/*
ending of the target, the file should be extracted.Waiting for comments or thumbs up before moving forward.