[python] 플라스크에서 정적 파일을 제공하는 방법

그래서 이것은 창피합니다. 나는 함께 던진 응용 프로그램을 가지고 있으며 Flask현재 CSS와 JS에 대한 링크가있는 단일 정적 HTML 페이지를 제공하고 있습니다. 그리고 문서에서 Flask정적 파일 반환에 대해 설명 하는 곳을 찾을 수 없습니다 . 예, 사용할 수는 render_template있지만 데이터가 템플릿 화되지 않았다는 것을 알고 있습니다. 나는 생각 send_file했거나 url_for옳았지만 그것들을 작동시키지 못했습니다. 그 동안 파일을 열고 내용을 읽고 Response적절한 mimetype으로 리깅합니다 .

import os.path

from flask import Flask, Response


app = Flask(__name__)
app.config.from_object(__name__)


def root_dir():  # pragma: no cover
    return os.path.abspath(os.path.dirname(__file__))


def get_file(filename):  # pragma: no cover
    try:
        src = os.path.join(root_dir(), filename)
        # Figure out how flask returns static files
        # Tried:
        # - render_template
        # - send_file
        # This should not be so non-obvious
        return open(src).read()
    except IOError as exc:
        return str(exc)


@app.route('/', methods=['GET'])
def metrics():  # pragma: no cover
    content = get_file('jenkins_analytics.html')
    return Response(content, mimetype="text/html")


@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def get_resource(path):  # pragma: no cover
    mimetypes = {
        ".css": "text/css",
        ".html": "text/html",
        ".js": "application/javascript",
    }
    complete_path = os.path.join(root_dir(), path)
    ext = os.path.splitext(path)[1]
    mimetype = mimetypes.get(ext, "text/html")
    content = get_file(complete_path)
    return Response(content, mimetype=mimetype)


if __name__ == '__main__':  # pragma: no cover
    app.run(port=80)

누군가 코드 샘플이나 URL을 제공하고 싶습니까? 나는 이것이 간단하게 죽을 것이라는 것을 안다.



답변

선호되는 방법은 nginx 또는 다른 웹 서버를 사용하여 정적 파일을 제공하는 것입니다. 그들은 플라스크보다 더 효율적으로 할 수 있습니다.

그러나 send_from_directory디렉토리에서 파일을 보내는 데 사용할 수 있으며 일부 상황에서는 매우 편리합니다.

from flask import Flask, request, send_from_directory

# set the project root directory as the static folder, you can set others.
app = Flask(__name__, static_url_path='')

@app.route('/js/<path:path>')
def send_js(path):
    return send_from_directory('js', path)

if __name__ == "__main__":
    app.run()

마십시오 하지 사용 send_file하거나 send_static_file사용자가 제공하는 경로.

send_static_file 예:

from flask import Flask, request
# set the project root directory as the static folder, you can set others.
app = Flask(__name__, static_url_path='')

@app.route('/')
def root():
    return app.send_static_file('index.html')


답변

정적 파일의 위치를 ​​이동하려는 경우 가장 간단한 방법은 생성자에서 경로를 선언하는 것입니다. 아래 예에서 템플릿과 정적 파일을이라는 하위 폴더로 옮겼습니다 web.

app = Flask(__name__,
            static_url_path='',
            static_folder='web/static',
            template_folder='web/templates')
  • static_url_path=''URL에서 선행 경로를 제거합니다 (예 : default /static).
  • static_folder='web/static'폴더에서 찾은 모든 파일
    web/static을 정적 파일로 제공합니다.
  • template_folder='web/templates' 마찬가지로 템플릿 폴더가 변경됩니다.

이 방법을 사용하면 다음 URL은 CSS 파일을 반환합니다.

<link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css">

마지막으로 flask_server.pyFlask 인스턴스가있는 폴더 구조를 살펴 보겠습니다.

중첩 된 정적 플라스크 폴더


답변

또한 내가 가장 좋아하는 폴더는 고정 경로로 폴더를 설정하여 모든 사람이 내부 파일에 접근 할 수 있도록합니다.

app = Flask(__name__, static_url_path='/static')

이 세트를 사용하면 표준 HTML을 사용할 수 있습니다.

<link rel="stylesheet" type="text/css" href="/static/style.css">


답변

나는 당신이 거기에 필요한 것을 찾을 것이라고 확신합니다 : http://flask.pocoo.org/docs/quickstart/#static-files

기본적으로 패키지 루트에 “static”폴더 만 있으면 http://example.com/static/foo.barurl_for('static', filename='foo.bar') 를 사용하여 파일을 직접 사용 하거나 파일에 연결할 수 있습니다 . .

편집 : 의견에서 제안한 것처럼 '/static/foo.bar'URL 경로를 직접 사용할 수 있지만 url_for() 오버 헤드 (성능 현명한)는 매우 낮으므로 나중에 동작을 쉽게 사용자 정의 할 수 있습니다 (폴더 변경, URL 경로 변경, 정적 파일을 S3 등으로 이동하십시오.


답변

이 기능을 사용할 수 있습니다 :

send_static_file(filename)
정적 파일을 정적 폴더에서 브라우저로 보내는 데 내부적으로 사용되는 기능입니다.

app = Flask(__name__)
@app.route('/<path:path>')
def static_file(path):
    return app.send_static_file(path)


답변

내가 사용하고 잘 작동하는 것은 “템플릿”디렉토리와 “정적”디렉토리입니다. 모든 .html 파일 / Flask 템플릿을 templates 디렉토리 안에 넣고 static에는 CSS / JS가 포함되어 있습니다. render_template는 Flask의 템플릿 구문을 사용한 정도에 관계없이 일반적인 HTML 파일에 대해 잘 작동합니다. 아래는 views.py 파일의 샘플 호출입니다.

@app.route('/projects')
def projects():
    return render_template("projects.html", title = 'Projects')

별도의 정적 디렉토리에서 일부 정적 파일을 참조하려는 경우 url_for ()를 사용하십시오. 어쨌든 html의 CSS / JS 파일 링크 에서이 작업을 수행하게 될 것입니다. 예를 들어 …

<script src="{{ url_for('static', filename='styles/dist/js/bootstrap.js') }}"></script>

다음은 “정식”비공식 Flask 튜토리얼에 대한 링크입니다. 여기에 유용한 팁이 많이 있습니다.

http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world


답변

다른 답변을 기반으로 한 가장 간단한 작업 예는 다음과 같습니다.

from flask import Flask, request
app = Flask(__name__, static_url_path='')

@app.route('/index/')
def root():
    return app.send_static_file('index.html')

if __name__ == '__main__':
  app.run(debug=True)

index.html 이라는 HTML을 사용하여 :

<!DOCTYPE html>
<html>
<head>
    <title>Hello World!</title>
</head>
<body>
    <div>
         <p>
            This is a test.
         </p>
    </div>
</body>
</html>

중요 : 그리고 index.htmlstatic 이라는 폴더 에 있습니다. 즉 <projectpath>, .py파일 <projectpath>\static이 있고html 파일을.

서버가 네트워크에 표시되도록하려면 app.run(debug=True, host='0.0.0.0')

편집 : 요청하면 폴더의 모든 파일을 표시하려면 다음을 사용하십시오.

@app.route('/<path:path>')
def static_file(path):
    return app.send_static_file(path)

본질적으로 BlackMamba답이므로 공감하십시오.