How do I get FastAPI to do SSR for Vue 3? - python

According to this documentation for Vue's SSR, it is possible to use node.js to render an app and return it using an express server. Is is possible to do the same with FastAPI?
Or is using Jinja2 templates or SPA the only solution?
Problems:
No SPA: To help with SEO
No SSG: Too many pages will be generated. Some need to be generated dynamically.
No Jinja2/Python Templates: Node modules aren't built, bundled and served. All modules have to served from a remote package CDN.
I have a feeling that maybe changing the Vue 3 delimiters and then building the project and serving the files as Jinja2 templates is the solution, but I'm not sure how it would work with Vue's routers. I know the /dist folder can be served on the default route and then use a catchall can be used to display files that do exist.
Possible Solution
#app.get("/", response_class=FileResponse)
def read_index(request: Request):
index = f"{static_folder}/index.html"
return FileResponse(index)
#app.get("/{catchall:path}", response_class=FileResponse)
def read_index(request: Request):
path = request.path_params["catchall"]
file = static_folder + path
if os.path.exists(file):
return FileResponse(file)
index = f"{static_folder}/index.html"
return FileResponse(index)
Questions
If there is a way to do SSR with FastAPI and Vue 3, what is it?
If there is no direct way, how do I combine Vue's built /dist with Jinja2 templates to serve dynamic pages?

There are several options available, such as Nuxt.js, Quasar, and Gridsome, which provide support for SSR with FastAPI and Vue 3.

Related

django-tenants: access tenant media files in script

I am running an app built with djang-tenants. The app asks the user (tenant) to upload some data. I want the data to be segregated in sub directories for each tenant.
Acccording to the doc (https://django-tenants.readthedocs.io/en/latest/files.html), here is how media root is configured:
settings.py
MEDIA_ROOT = "/Users/murcielago/desktop/simulation_application/data"
MULTITENANT_RELATIVE_MEDIA_ROOT = "%s"
On the upload everything is great.
Now, I can't find a way to retrieve the file being uploaded within the app. Basically I need the app to serve the file corresponding to which tenant is requesting it.
Here is how I thought this would work:
from django.conf import settings
media_file_dir = settings.MULTITENANT_RELATIVE_MEDIA_ROOT
df = pd.read_csv(media_file_dir+'/uploads/sample_orders_data.csv')
but this does not work.
I have made it work so far grabbing the tenant name from the url and passing it to the app using pickle but this is not right in terms of security and won't scale.
Would someone has a clue on the best way to handle the lecture of tenant specific files?

Flask app rendering some variable urls from HTML docs in folder but not others HTML docs in the same folder

My Flask app renders all templates in the template folder, including all blog posts in a blog folder within the templates folder. However, I have the exact structure for my app's glossary as I have for the blog - a folder called 'glossary' within the templates folder. But, it's quirky. It renders some html documents but not others from that same folder. It renders 0-day.html every time I click a link with that dynamic url or directly type in /0-day; but not act.html using /act. I have 180 html files in the glossary folder and about half render and the rest return a 404.
I've been researching this for a month now, and today I switched the glossary structure by creating a blueprint instead. I used this tutorial: https://www.youtube.com/watch?v=WteIH6J9v64. I got everything running as normal, except the same issue with the glossary persists with the blueprint setup as well.
Assuming everything else works, and it does:
Glossary Term:
#glossary.route("<termname>", methods=["POST","GET"])
def term(termname='story'):
try:
visits(termname)
return render_template(f"{termname}.html", glossary=True, termname=termname)
except Exception as e:
return page_not_found(e)
As you can see below, I have my blog setup the same way:
Blog Posts
#app.route("/blog/<postname>", methods=["POST","GET"])
def post(postname='distant-idealism-introduction'):
try:
visits(postname)
return render_template(f"/blog/{postname}.html", blog=True, postname=postname)
except Exception as e:
return page_not_found(e)
The only difference is that the blog is routed from the routes.py now and the glossary terms from the glossary.py blueprint. However, when there was no blueprint I was rendering everything from the routes.py file, so the blueprint setup is not the cause.
I apologize, but because this problem is so confusing, I don't know what else to add. It's even difficult to research because I always get results like the YouTube video above - either about blueprints, building routes, or something Flask in general. I never get any search result even close to my issue. If more info is required just let me know, please.
Thank you in advance.
Some problems I found:
The URL rule is missing a start slash:
#glossary.route("/<termname>", methods=["POST","GET"])
Since your templates about glossaries were put in a glossary folder, your template path should be /glossary/act.html:
return render_template(f"/glossary/{termname}.html", glossary=True, termname=termname)

route endpoint conflicts when generating sphinx doc for flask restful api

I'm trying to build documentation for a Flask webapp that includes a REST-like API built into it. I'm using sphinx, specifically the httpdomain extension from sphinxcontrib, using the autohttp.flask module to auto-generate my Flask docs, and the autohttp.qrefflask module to auto-generate a quick reference table to go along with it. However, when I try to build my sphinx docs (make html), I'm running into the error of conflicting route endpoints
Exception occurred:
File "/Users/../anaconda2/lib/python2.7/site-packages/flask/app.py", line 1051, in add_url_rule
'existing endpoint function: %s' % endpoint)
AssertionError: View function mapping is overwriting an existing endpoint function: api.View1:add_config
I only really care about generating documentation for my API and none of the Flask web routes, so I've restricted my sphinx documentation to only build the api blueprints. Here is my sphinx api.rst
.. qrefflask:: myapp.web:create_app(debug=True)
:undoc-static:
:endpoints:
:blueprints: api
:order: path
.. autoflask:: myapp.web:create_app(debug=True)
:undoc-static:
:endpoints:
:blueprints: api
:order: path
My Flask app and Blueprint layout is as follows:
myapp/
api/
__init__.py (api blueprint defined here)
view1.py
view2.py
view3.py
web/
__init__.py (main Flask app created here via create_app)
I'm wondering if it's a problem with how I'm registering the blueprint, and that sphinx somehow is registering it twice, but I don't understand it.
My api.__init__.py basically has my Blueprint definition and a few custom error handlers:
from flask import Blueprint, jsonify
theapi = Blueprint("api", __name__, url_prefix='/myapp/api')
#theapi.errorhandler(500)
def internal_server_error(err):
messages = {'error': 'internal_server_error',
'message': err.description,
'traceback': get_traceback(asstring=True)}
return jsonify({
'api_error': messages,
}), 500
while my main Flask app creation, web.__init__.py just imports this and registers everything:
def create_app(debug=False, local=False):
from myapp.api import theapi as api
from myapp.api.view1 import View1
...
app = Flask(__name__, static_url_path='/myapp/static')
...
View1.register(api)
app.register_blueprint(api)
return app
If I move the api blueprint definition and error_handlers into the main app creation, everything works fine. But then that breaks the modularity of it. I'd like to keep my api stuff inside the api module. Also, if remove either the main autoflask or qrefflask generation, and only use one, everything works fine. But I'd really like to have the quick reference guide. The code itself runs fine, but the damn documentation is failing to build. Does anyone have any suggestions?

Define a base route when using flask blueprints

I am currently using blueprints in my flask application. However, I would like to define a simple 'base' route ( '/' ) e.g. myapp.com/
How can I do this?
IMHO, this has nothing to do with Flask. To create route to home page, You would do something like this:
#app.route
def index():
return render_template('index.html')
Visiting / on any site where this Flask app is deployed would lead to home page.
Now, in order to lead You to myapp.com/, You need to get myapp.com address, meaning You would need to buy that domain.

zope template namespaces gone?

Where can I find the zope namespaces for my templates? I setup a pyramid project using SQLAlchemy + URL dispatch + Chameleon templates. These URLs don't exist anymore...
http://xml.zope.org/namespaces/tal
http://xml.zope.org/namespaces/metal
Thanks.
The TAL specification says:
This is not a URL, but merely a unique identifier. Do not expect a browser to resolve it successfully.
http://wiki.zope.org/ZPT/TALSpecification14

Categories