Programing

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

lottogame 2020. 2. 18. 21:53
반응형

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


그래서 이것은 창피합니다. 나는 함께 던진 응용 프로그램을 가지고 있으며 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')

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

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

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


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

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

해당 세트로 표준 HTML을 사용할 수 있습니다.

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

정적 파일의 위치를 ​​이동하려는 경우 가장 간단한 방법은 생성자에서 경로를 선언하는 것입니다. 아래 예에서 템플릿과 정적 파일을이라는 하위 폴더로 옮겼습니다 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'Flask가에서 찾은 파일을 제공하도록 지시합니다 web/static.
  • template_folder='web/templates'마찬가지로 템플릿 폴더가 변경됩니다.

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

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

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

중첩 된 정적 플라스크 폴더


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

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.html을이 폴더라는에 정적 의미 <projectpath>.py파일을, 그리고 <projectpath>\statichtml파일을.

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

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

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

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


다음 폴더 트리를 작성하는 각도 + 보일러 플레이트 흐름의 경우 :

backend/
|
|------ui/
|      |------------------build/          <--'static' folder, constructed by Grunt
|      |--<proj           |----vendors/   <-- angular.js and others here
|      |--     folders>   |----src/       <-- your js
|                         |----index.html <-- your SPA entrypoint 
|------<proj
|------     folders>
|
|------view.py  <-- Flask app here

다음 솔루션을 사용합니다.

...
root = os.path.join(os.path.dirname(os.path.abspath(__file__)), "ui", "build")

@app.route('/<path:path>', methods=['GET'])
def static_proxy(path):
    return send_from_directory(root, path)


@app.route('/', methods=['GET'])
def redirect_to_index():
    return send_from_directory(root, 'index.html')
...

'정적'폴더를 사용자 정의로 재정의하는 데 도움이됩니다.


그래서 (@ user1671599 답변을 기반으로) 작동하는 것들을 얻었고 여러분과 공유하고 싶었습니다.

(Python의 첫 번째 앱이므로 올바르게하고 싶습니다.)

저는 이것을 했어요 -

프로젝트 구조 :

여기에 이미지 설명을 입력하십시오

server.py :

from server.AppStarter import AppStarter
import os

static_folder_root = os.path.join(os.path.dirname(os.path.abspath(__file__)), "client")

app = AppStarter()
app.register_routes_to_resources(static_folder_root)
app.run(__name__)

AppStarter.py :

from flask import Flask, send_from_directory
from flask_restful import Api, Resource
from server.ApiResources.TodoList import TodoList
from server.ApiResources.Todo import Todo


class AppStarter(Resource):
    def __init__(self):
        self._static_files_root_folder_path = ''  # Default is current folder
        self._app = Flask(__name__)  # , static_folder='client', static_url_path='')
        self._api = Api(self._app)

    def _register_static_server(self, static_files_root_folder_path):
        self._static_files_root_folder_path = static_files_root_folder_path
        self._app.add_url_rule('/<path:file_relative_path_to_root>', 'serve_page', self._serve_page, methods=['GET'])
        self._app.add_url_rule('/', 'index', self._goto_index, methods=['GET'])

    def register_routes_to_resources(self, static_files_root_folder_path):

        self._register_static_server(static_files_root_folder_path)
        self._api.add_resource(TodoList, '/todos')
        self._api.add_resource(Todo, '/todos/<todo_id>')

    def _goto_index(self):
        return self._serve_page("index.html")

    def _serve_page(self, file_relative_path_to_root):
        return send_from_directory(self._static_files_root_folder_path, file_relative_path_to_root)

    def run(self, module_name):
        if module_name == '__main__':
            self._app.run(debug=True)

공유의 생각 ....이 예.

from flask import Flask
app = Flask(__name__)

@app.route('/loading/')
def hello_world():
    data = open('sample.html').read()    
    return data

if __name__ == '__main__':
    app.run(host='0.0.0.0')

이것은 더 좋고 간단하게 작동합니다.


간단한 방법 중 하나입니다. 건배!

demo.py

from flask import Flask, render_template
app = Flask(__name__)

@app.route("/")
def index():
   return render_template("index.html")

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

이제 templates 라는 폴더 이름을 만듭니다 . 템플릿 폴더 안에 index.html 파일 추가

index.html

<!DOCTYPE html>
<html>
<head>
    <title>Python Web Application</title>
</head>
<body>
    <div>
         <p>
            Welcomes You!!
         </p>
    </div>
</body>
</html>

프로젝트 구조

-demo.py
-templates/index.html

from flask import redirect, url_for
...
@app.route('/', methods=['GET'])
def metrics():
    return redirect(url_for('static', filename='jenkins_analytics.html'))

이 서버는 html 파일에서 참조 된 모든 파일 (css 및 js ...)을 서버에 저장합니다.


모든 대답은 훌륭하지만 나에게 잘 맞는 것은 send_fileFlask 의 간단한 기능 사용하는 것 입니다. host : port / ApiName 이 브라우저에 파일 출력을 표시 할 때 html 파일을 응답으로 보내야 할 때 잘 작동 합니다.


@app.route('/ApiName')
def ApiFunc():
    try:
        return send_file('some-other-directory-than-root/your-file.extension')
    except Exception as e:
        logging.info(e.args[0])```


   기본적으로 모든 템플릿 파일 (모든 일반 텍스트 파일,하지만 일반적으로 포함하는 "템플릿"폴더를 사용 플라스크 .html모든 정적 파일을 포함하거나 jinja2 같은 템플릿 언어의 일종)는 "정적"폴더 (예 : .js .css및 이미지).
   당신의에서 routes, u는 사용할 수 있습니다 render_template()(나는 그것이 배치됩니다 기본적으로, 위에서 말한대로 템플릿 파일을 렌더링하기 위해 templates귀하의 요청에 대한 응답으로 폴더). 그리고 템플릿 파일 (보통 .html과 같은 파일)에서 u는 일부 .js및 / 또는 '.css'파일을 사용할 수 있으므로이 정적 파일을 현재 템플릿 파일에 어떻게 연결하는지 궁금합니다.


파일을 열려고하면을 사용할 수 있습니다 app.open_resource(). 따라서 파일을 읽는 것은 다음과 같습니다

with app.open_resource('/static/path/yourfile'):
      #code to read the file and do something

참고 URL : https://stackoverflow.com/questions/20646822/how-to-serve-static-files-in-flask

반응형