mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
fix web server handling of rel and abs outdir paths (#550)
* fix web server handling of rel and abs outdir paths * Can now specify either a relative or absolute path for outdir * Outdir path does not need to be inside the stable-diffusion directory * Closes security hole that allowed user to read any file within stable-diffusion (eek!) * Closes #536
This commit is contained in:
parent
e6179af46a
commit
5818528aa6
@ -36,7 +36,7 @@ Outputs:
|
||||
|
||||
The one with seed 3357757885 looks nice:
|
||||
|
||||
<img src="assets/variation_walkthru/000001.3357757885.png"/>
|
||||
<img src="../assets/variation_walkthru/000001.3357757885.png"/>
|
||||
|
||||
---
|
||||
|
||||
@ -65,8 +65,8 @@ variation amount used to generate it.
|
||||
|
||||
This gives us a series of closely-related variations, including the two shown here.
|
||||
|
||||
<img src="assets/variation_walkthru/000002.3647897225.png">
|
||||
<img src="assets/variation_walkthru/000002.1614299449.png">
|
||||
<img src="../assets/variation_walkthru/000002.3647897225.png">
|
||||
<img src="../assets/variation_walkthru/000002.1614299449.png">
|
||||
|
||||
I like the expression on Xena's face in the first one (subseed 3647897225), and the armor on her shoulder in the second one (subseed 1614299449). Can we combine them to get the best of both worlds?
|
||||
|
||||
@ -81,7 +81,7 @@ Outputs:
|
||||
|
||||
Here we are providing equal weights (0.1 and 0.1) for both the subseeds. The resulting image is close, but not exactly what I wanted:
|
||||
|
||||
<img src="assets/variation_walkthru/000003.1614299449.png">
|
||||
<img src="../assets/variation_walkthru/000003.1614299449.png">
|
||||
|
||||
We could either try combining the images with different weights, or we can generate more variations around the almost-but-not-quite image. We do the latter, using both the `-V` (combining) and `-v` (variation strength) options. Note that we use `-n6` to generate 6 variations:
|
||||
|
||||
@ -98,7 +98,7 @@ Outputs:
|
||||
|
||||
This produces six images, all slight variations on the combination of the chosen two images. Here's the one I like best:
|
||||
|
||||
<img src="assets/variation_walkthru/000004.3747154981.png">
|
||||
<img src="../assets/variation_walkthru/000004.3747154981.png">
|
||||
|
||||
As you can see, this is a very powerful tool, which when combined with subprompt weighting, gives you great control over the content and
|
||||
quality of your generated images.
|
||||
|
@ -152,21 +152,27 @@ You might also need to install Rust (I mention this again below).
|
||||
|
||||
### How many snakes are living in your computer?
|
||||
|
||||
Here's the reason why you have to specify which python to use.
|
||||
There are several versions of python on macOS and the computer is
|
||||
picking the wrong one. More specifically, preload_models.py and dream.py says to
|
||||
find the first `python3` in the path environment variable. You can see which one
|
||||
it is picking with `which python3`. These are the mostly likely paths you'll see.
|
||||
You might have multiple Python installations on your system, in which case it's
|
||||
important to be explicit and consistent about which one to use for a given project.
|
||||
This is because virtual environments are coupled to the Python that created it (and all
|
||||
the associated 'system-level' modules).
|
||||
|
||||
When you run `python` or `python3`, your shell searches the colon-delimited locations
|
||||
in the `PATH` environment variable (`echo $PATH` to see that list) in that order - first match wins.
|
||||
You can ask for the location of the first `python3` found in your `PATH` with the `which` command like this:
|
||||
|
||||
% which python3
|
||||
/usr/bin/python3
|
||||
|
||||
The above path is part of the OS. However, that path is a stub that asks you if
|
||||
you want to install Xcode. If you have Xcode installed already,
|
||||
/usr/bin/python3 will execute /Library/Developer/CommandLineTools/usr/bin/python3 or
|
||||
/Applications/Xcode.app/Contents/Developer/usr/bin/python3 (depending on which
|
||||
Anything in `/usr/bin` is [part of the OS](https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW6). However, `/usr/bin/python3` is not actually python3, but
|
||||
rather a stub that offers to install Xcode (which includes python 3). If you have Xcode installed already,
|
||||
`/usr/bin/python3` will execute `/Library/Developer/CommandLineTools/usr/bin/python3` or
|
||||
`/Applications/Xcode.app/Contents/Developer/usr/bin/python3` (depending on which
|
||||
Xcode you've selected with `xcode-select`).
|
||||
|
||||
Note that `/usr/bin/python` is an entirely different python - specifically, python 2. Note: starting in
|
||||
macOS 12.3, `/usr/bin/python` no longer exists.
|
||||
|
||||
% which python3
|
||||
/opt/homebrew/bin/python3
|
||||
|
||||
@ -176,17 +182,21 @@ for Homebrew binaries before system ones, you'll see the above path.
|
||||
% which python
|
||||
/opt/anaconda3/bin/python
|
||||
|
||||
If you drop the "3" you get an entirely different python. Note: starting in
|
||||
macOS 12.3, /usr/bin/python no longer exists (it was python 2 anyway).
|
||||
|
||||
If you have Anaconda installed, this is what you'll see. There is a
|
||||
/opt/anaconda3/bin/python3 also.
|
||||
If you have Anaconda installed, you will see the above path. There is a
|
||||
`/opt/anaconda3/bin/python3` also. We expect that `/opt/anaconda3/bin/python`
|
||||
and `/opt/anaconda3/bin/python3` should actually be the *same python*, which you can
|
||||
verify by comparing the output of `python3 -V` and `python -V`.
|
||||
|
||||
(ldm) % which python
|
||||
/Users/name/miniforge3/envs/ldm/bin/python
|
||||
|
||||
This is what you'll see if you have miniforge and you've correctly activated
|
||||
the ldm environment. This is the goal.
|
||||
The above is what you'll see if you have miniforge and you've correctly activated
|
||||
the ldm environment, and you used option 2 in the setup instructions above ("no pyenv").
|
||||
|
||||
(anaconda3-2022.05) % which python
|
||||
/Users/name/.pyenv/shims/python
|
||||
|
||||
... and the above is what you'll see if you used option 1 ("Alongside pyenv").
|
||||
|
||||
It's all a mess and you should know [how to modify the path environment variable](https://support.apple.com/guide/terminal/use-environment-variables-apd382cc5fa-4f58-4449-b20a-41c53c006f8f/mac)
|
||||
if you want to fix it. Here's a brief hint of all the ways you can modify it
|
||||
@ -201,6 +211,13 @@ if you want to fix it. Here's a brief hint of all the ways you can modify it
|
||||
Which one you use will depend on what you have installed except putting a file
|
||||
in /etc/paths.d is what I prefer to do.
|
||||
|
||||
Finally, to answer the question posed by this section's title, it may help to list
|
||||
all of the `python` / `python3` things found in `$PATH` instead of just the one that
|
||||
will be executed by default. To do that, add the `-a` switch to `which`:
|
||||
|
||||
% which -a python3
|
||||
...
|
||||
|
||||
### Debugging?
|
||||
|
||||
Tired of waiting for your renders to finish before you can see if it
|
||||
|
@ -103,10 +103,14 @@ class DreamServer(BaseHTTPRequestHandler):
|
||||
self.end_headers()
|
||||
self.wfile.write(bytes('{}', 'utf8'))
|
||||
else:
|
||||
path = "." + self.path
|
||||
cwd = os.path.realpath(os.getcwd())
|
||||
is_in_cwd = os.path.commonprefix((os.path.realpath(path), cwd)) == cwd
|
||||
if not (is_in_cwd and os.path.exists(path)):
|
||||
path_dir = os.path.dirname(self.path)
|
||||
out_dir = os.path.realpath(self.outdir.rstrip('/'))
|
||||
if self.path.startswith('/static/dream_web/'):
|
||||
path = '.' + self.path
|
||||
elif out_dir.endswith(path_dir):
|
||||
file = os.path.basename(self.path)
|
||||
path = os.path.join(self.outdir,file)
|
||||
else:
|
||||
self.send_response(404)
|
||||
return
|
||||
mime_type = mimetypes.guess_type(path)[0]
|
||||
@ -114,7 +118,7 @@ class DreamServer(BaseHTTPRequestHandler):
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", mime_type)
|
||||
self.end_headers()
|
||||
with open("." + self.path, "rb") as content:
|
||||
with open(path, "rb") as content:
|
||||
self.wfile.write(content.read())
|
||||
else:
|
||||
self.send_response(404)
|
||||
|
Loading…
Reference in New Issue
Block a user