-1

I got some understanding of how to create a webpage using Python Flask to display a png image from these webpages:

This is my Python Flask code:

template_dir = "/home/maxloo/pyrest/"
static_dir = "/home/maxloo/pyrest/static"
app = Flask(__name__, template_folder=template_dir, static_url_path=static_dir)

@app.route("/petri/<uuid>")
def getPetriFile(uuid):
  dirPath = template_dir + "temp/workdir/" + uuid + "/petri/"
  dotPath = dirPath + "LATEST"
  petriFolder = static_dir + "/temp/workdir/" + uuid + "/petri/"
  if not os.path.exists(petriFolder):
    Path(petriFolder).mkdir(parents=True, exist_ok=True)
  petriPath = petriFolder + "LATEST.png"
  templatePetriPath = "/temp/workdir/" + uuid + "/petri/LATEST.png"
  return render_template("image.html", user_image = templatePetriPath)

This is my HTML code:

<!DOCTYPE html>
<html>
<head>
  <title>Index</title>
</head>
<body>
  <img src="{{ user_image }}" alt="User Image">
  <object type="image/png" data="{{ user_image }}">
  </object>
</body>
</html>

However, the web page could not display the image. Can anyone help? The images I use and the folders that contain them are dynamically generated. Only the template parent directory is static.

I've amended my code to include static_url_path, but it still did not display the image.

This is the output of running the tree command:

┌─[20220629-08:57:28]   [maxloo@:~/pyrest/static]
└─[0] <> tree
.
├── LATEST.png
└── temp
    └── workdir
        └── 28d023bd-84e7-445a-8488-1e8aeb1fd50a
            └── petri
                └── LATEST.png
4 directories, 2 files

I've even tried this Python Flask code:

template_dir = "/home/maxloo/pyrest/"
static_dir = "/home/maxloo/pyrest/static/"
app = Flask(__name__, template_folder=template_dir, static_url_path=static_dir)
app.static_url_path = static_dir
for rule in app.url_map.iter_rules('static'):
  app.url_map._rules.remove(rule)
app.url_map._rules_by_endpoint['static'] = []
app.view_functions["static"] = None
app.add_url_rule(static_dir + "LATEST.png",
  endpoint='static',
  view_func=app.send_static_file)

@app.route("/petri/<uuid>")
def getPetriFile(uuid):
  petriPath = static_dir + "LATEST.png"
  return render_template("image.html", user_image = static_dir)

I've left out most of the code in def getPetriFile(uuid): because they are only required for the generation of the dynamic image file LATEST.png.

maxloo
  • 453
  • 2
  • 12
  • 1
    `template_folder` is used for templates or HTML/Jinja Files. Where as `static_folder` is used for serving static assets like javascript, css, images or any other static files. So you need to create your dynamic folder within static folder so it can be served. – GodWin1100 Jun 28 '22 at 23:12
  • @GodWin, I've changed my code to include `static_url_path`, but it still did not work... – maxloo Jun 28 '22 at 23:43
  • @GodWin, I do not use config.py. I could not find any config.py file in my root folder for the application. – maxloo Jun 29 '22 at 00:21
  • you create folder dynamically but you have to also put image in this folder. later you create path to image but this image may not exist in this folder. Did you check if you have image in this folder on disk? – furas Jun 29 '22 at 00:58
  • @furas, I've added the output of running the `tree` command in my post. The image file is generated successfully. – maxloo Jun 29 '22 at 01:03
  • you could use `print()` to see if you have correct values in variables. And you could use `os.path.exists` to check if it can find file when you run code. Maybe you don't have this file when you run code but it adds it later. – furas Jun 29 '22 at 01:04
  • and you should check if you can open this `LATEST.png` in any image browser - maybe file is broken and web browser can't display it. – furas Jun 29 '22 at 01:06
  • check path in you new code - you send `user_image = static_dir` - so you send path to folder but you have to send path to image `user_image = "/LATEST.png"` or `user_image = "/temp/workdir/28d023bd-84e7-445a-8488-1e8aeb1fd50a.petri/LATEST.png"`. Maybe see directly in `HTML` in browser what path you generated. – furas Jun 29 '22 at 02:04
  • I'm not sure but maybe it always needs path with prefix `/static` - like. `"/static/LATEST.png"` because flask may use `/static` to recognize path to image and use some built-in `router("/static/")`. – furas Jun 29 '22 at 02:08

1 Answers1

1

I'm not sure but all problem can be because Flask has two variables for static files: static_url_path and static_folder. And your code mess these variables

Flask(static_folder=..., static_url_path=...)

static_url_path defines URL, not path to file on disk.

If you set

Flask(static_url_path="/home/maxloo/pyrest/static")

then URL in html has to start with /home/maxloo/pyrest/static

<img src="/home/maxloo/pyrest/static/temp/workdir/28d023bd-84e7-445a-8488-1e8aeb1fd50a/petri/LATEST.png"

but it will search images in local folder static (default is Flask(static_folder="static"))


static_folder defines local folder in which it has to search files

If you set

Flask(static_folder="/home/maxloo/pyrest/static")

then it searchs in local folder /home/maxloo/pyrest/static but url will have to start with default /static

<img src="/static/temp/workdir/28d023bd-84e7-445a-8488-1e8aeb1fd50a/petri/LATEST.png"

It will convert url src=/static/<path> to local path /home/maxloo/pyrest/static/<path> like in code

@app.router("/static/<path>")   # <static_url_path>/<path>
def static(path):
    return send_from_directory(static_folder, path)  # (static_dir, path)

So your code may need static_folder=static_dir instead of static_url_path=static_dir and url = "/static/..."

from flask import Flask

template_dir = "/home/maxloo/pyrest"
static_dir   = "/home/maxloo/pyrest/static"

app = Flask(__name__, template_folder=template_dir, static_folder=static_dir)#, static_url_path='/static')

@app.route("/petri/<uuid>")
def getPetriFile(uuid):
    petri_folder = f'{static_dir}/temp/workdir/{uuid}/petri/'
    
    if not os.path.exists(petri_folder):
        Path(petri_folder).mkdir(parents=True, exist_ok=True)
        # copy some file to folder
        shutil.copy(f'{static_dir}/LATEST.png', f'{petri_folder}/LATEST.png')
        
    # it has to start with `/static`
    image_url = f"/static/temp/workdir/{uuid}/petri/LATEST.png"
    
    return render_template("image.html", user_image=image_url)
furas
  • 134,197
  • 12
  • 106
  • 148