Question:
So I am making a Framework in Python similar to Flask but instead of HTML it is only Python (as some find it easier this way). I want to be able to add styles but I can’t figure out how to link a CSS and JS file to my app.py
file.
Repl link:
https://replit.com/@SalladShooter/VIAL
app.py
from werkzeug.exceptions import HTTPException, NotFound
from werkzeug.wrappers import Request, Response
from werkzeug.serving import run_simple
from werkzeug.routing import Map, Rule
from src import App, route, tags
class MyApp(App):
def __init__(self):
self.url_map = Map([
Rule('/', endpoint='index')
])
def dispatch_request(self, request):
adapter = self.url_map.bind_to_environ(request.environ)
try:
endpoint, args = adapter.match()
handler = getattr(self, endpoint)
if handler is None:
raise NotFound("Endpoint not found")
return handler(request, **args)
except HTTPException as e:
return e
except Exception as e:
return Response(f"An error occurred: {str(e)}", status=500)
def index(self, request):
html_content = []
list_items = [
tags.li("Item 1"),
tags.li("Item 2"),
tags.li("Item 3")
]
html_content.append(str(tags.ul().add_children(*list_items)))
html_content.append(str(tags.p("Hello, World!").attribute('class', 'p').id('p').add_children(tags.div())))
html_content.append(str(tags.h1("Hello, World!").attribute('class', 'h1').id('h1').add_children(tags.div())))
response = Response(html_content, mimetype='text/html')
return response
def serve_static(self, filename, directory):
path = os.path.join(directory, filename)
if os.path.isfile(path):
with open(path, 'rb') as f:
return Response(FileWrapper(f), mimetype=mimetypes.guess_type(path)[0])
else:
return NotFound("File not found")
def __call__(self, environ, start_response):
request = Request(environ)
response = self.dispatch_request(request)
return response(environ, start_response)
if __name__ == '__main__':
app = MyApp()
app.url_map.add(Rule('/static/styles.css/css', endpoint='serve_static'))
run_simple('0.0.0.0', 5000, app)
1 Like
You need to add a rule to serve static files from a dir named ‘static’, it should point to a generic path like /static/<filename>
and then use this path to serve any file from the static directory. And update the serve_static
method to take a filename parameter.
For example:
import os
import mimetypes #when you serve a file over HTTP, it's important to set the correct MIME type so that the client know how to handle the file.
from wekzeug.wsgi import FileWrapper
class MyApp(App):
def index(self, request):
# Link to your CSS and JS files
css_link = '<link rel="stylesheet" type="text/css" href="/static/styles.css">'
js_link = '<script src="/static/script.js"></script>'
html_content = [css_link, js_link]
def serve_static(self, filename):
directory = 'static' # Static files directory
path = os.path.join(directory, filename)
if __name__ == '__main__':
app = MyApp()
app.url_map.add(Rule('/static/<filename>', endpoint='serve_static'))
run_simple('0.0.0.0', 5000, app)
2 Likes
Hey @WindLother!
Thanks, I tried incorporating what you had but it throws errors (not specifics just 500
’s) →
172.31.196.55 - - [09/Feb/2024 20:54:40] "GET / HTTP/1.1" 200 -
172.31.196.55 - - [09/Feb/2024 20:54:40] "GET /static/styles.css HTTP/1.1" 500
172.31.196.55 - - [09/Feb/2024 20:54:40] "GET /static/script.js HTTP/1.1" 500 -
app.py
→
import mimetypes
from werkzeug.exceptions import HTTPException, NotFound
from werkzeug.wrappers import Request, Response
from werkzeug.serving import run_simple
from werkzeug.routing import Map, Rule
from werkzeug.wsgi import FileWrapper
from src import App, route, tags
class MyApp(App):
def __init__(self):
self.url_map = Map([
Rule('/', endpoint='index')
])
def dispatch_request(self, request):
adapter = self.url_map.bind_to_environ(request.environ)
try:
endpoint, args = adapter.match()
handler = getattr(self, endpoint)
if handler is None:
raise NotFound("Endpoint not found")
return handler(request, **args)
except HTTPException as e:
return e
except Exception as e:
return Response(f"An error occurred: {str(e)}", status=500)
def index(self, request):
css_link = '<link rel="stylesheet" type="text/css" href="/static/styles.css">'
js_link = '<script src="/static/script.js"></script>'
html_content = [css_link, js_link]
list_items = [
tags.li("Item 1"),
tags.li("Item 2"),
tags.li("Item 3")
]
html_content.append(str(tags.ul().add_children(*list_items)))
html_content.append(str(tags.p("Hello, World!").attribute('class', 'p').id('p').add_children(tags.div())))
html_content.append(str(tags.h1("Hello, World!").attribute('class', 'h1').id('h1').add_children(tags.div())))
response = Response(html_content, mimetype='text/html')
return response
def serve_static(self, filename, directory):
path = os.path.join(directory, filename)
if os.path.isfile(path):
with open(path, 'rb') as f:
return Response(FileWrapper(f), mimetype=mimetypes.guess_type(path)[0])
else:
return NotFound("File not found")
def __call__(self, environ, start_response):
request = Request(environ)
response = self.dispatch_request(request)
return response(environ, start_response)
def serve_static(self, filename):
directory = 'static' # Static files directory
path = os.path.join(directory, filename)
if __name__ == '__main__':
app = MyApp()
app.url_map.add(Rule('/static/<filename>', endpoint='serve_static'))
run_simple('0.0.0.0', 5000, app)
You’ve defined serve_static
twice in your code. The second definition is outside the MyApp
class and incomplete. Remove the second one.
1 Like
@WindLother Thank you, I followed your instructions and did a bit of troubleshooting and it worked!
This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.