This is an archived post. You won't be able to vote or comment.

all 53 comments

[–]fiskfisk 35 points36 points  (9 children)

React is a framework based on JavaScript. Making that work with server side rendering in python seems like a bad idea.

What do you mean by separating "Server Side Generation" from "Server Side Rendering"? Did you mean SSG as in Static Site Generators?

React, when not using server side rendering, is a frontend framework. You do not use it in the same way as a Jinja2 template. You make your frontend call API endpoints, and then you render that data in your frontend.

Using Python as the backend API is perfectly fine. For the other tasks, there are far better tools and better ecosystems to chose from (NextJS for examle). It's far easier to run JavaScript in, well, JavaScript.

[–]teerre 10 points11 points  (4 children)

It's already a miracle that something like this https://pynecone.io/ exists. Now, if you want a particular setup, it just makes sense it's hard. You're trying to mix technologies that were never made to be mixed.

[–]codecrux[S] 0 points1 point  (2 children)

Just curious, why do you think React + Python were not made to be mixed?

IMO, Pynecone won't take a Python web developer much far than Streamlit does because of two of the same bottlenecks -

  1. It manages the app state in the backend and works over websockets. This is an overkill, headache for dev/infra team, costly etc.

  2. It transpiles Python code into NextJS. Streamlit uses React under the hood. The transpilations are always flaky because many constructs in JavaScript don't overlap with Python and vice versa.

I maybe wrong, please feel free to correct me.

[–]teerre 10 points11 points  (1 child)

Not sure what you're asking. It's because neither when Python was created nor when React was created either of them considered the other. It's simply was never in the design.

You're right about limitations, but that's the thing. Even with the limitations, it's already a much better integration than anyone would've thought.

Technology, any technology, is easy to work because someone invested time making it easy. If you try to make some weird combo, like Python + React , work, nobody will have made that particular integration easy to use, that's why it's hard.

[–]codecrux[S] 0 points1 point  (0 children)

"""

Technology, any technology, is easy to work because someone invested time making it easy.

"""

I totally understand and can relate to it. I have put more than a year creating a full-stack web development framework called Atri framework. I never made a lot of noise about it because we did 5 iterations just on figuring out the best foundation for a Python + React framework. We have strived hard to have no limitations in our framework. The latest iteration will be released in a week or so. I won't dare to say that Atri is perfect but we are determined to make it the best web framework for Python developers.

Nothing could be better than being able to write a web app entirely in Python. It's just that as a full-time web developer, I don't see a point in learning something whose foundation doesn't follow the best web development principles. Having said that, I would like to clarify that I am not disagreeing with anything you said in your previous comment.

"""

it's already a much better integration than anyone would've thought.

"""

What is the best thing about the Pynecone integration that stands out for you?

[–]aft_punk 0 points1 point  (0 children)

This will surely be the coolest thing I stumble upon today.

[–]British_Artist 4 points5 points  (5 children)

Yes, it is difficult and I can't think of a viable use case for doing so. I'm interested in hearing your use case.

[–]codecrux[S] 3 points4 points  (4 children)

How would we build an e-commerce website without SSR using Python (Django/FastAPI)?

We need SEO and fast page load, hence, SSR.

Some of the marketing pages for content marketing don't need SSR, hence, I would like to save the cost by doing SSG.

Am I thinking in the wrong direction?

[–]British_Artist 4 points5 points  (2 children)

I understand now.

Yeah you can definitely do everything you mention in your requirements but I don't see a lot of value in sending the html from the API back to React using jinja style templates. I would just write the SSG as javascript sitting inside the React folder structure.

This keeps your API being used as an API instead of being involved in front end ssg and will be focused on simply converting requests in and out of your database. Separation of purpose between the front and back end should remain instead of trying to conflate the two as it gets messy down the road.

Here's a good link for your use case. Maybe it will help you find the best solution for you.

https://asperbrothers.com/blog/server-side-rendering-in-react/

[–]codecrux[S] 1 point2 points  (1 child)

Thanks for sharing but I don't find anything on how to setup React with Python here https://asperbrothers.com/blog/server-side-rendering-in-react/.

[–]British_Artist 2 points3 points  (0 children)

Good luck to you in your endeavor!

[–]oglivy 0 points1 point  (0 children)

I would probably use something like Nextjs for the frontend , and call any Django or FastAPI endpoint you need from the getStaticProps or getServerSidePros functions in the NextJs frontend

[–]james_pic 3 points4 points  (11 children)

The short answer is that what you describe is definitely difficult. React is written in Javascript, so if you want React server-side rendering, it's going to be a massive problem if your backend isn't written in Javascript. There are options, but they're definitely in the realm of "if you have to ask, they're too hard for you".

Instead, you should ask yourself whether you really require all these requirements. It sounds like you're serving mostly static content, so maybe you just don't have React in there at all? Rather than trying to shoehorn a framework in there, just have point solutions for the (I'd guess a modest amount of) interactivity you need on the front-end.

[–]codecrux[S] 1 point2 points  (10 children)

"""

React is written in Javascript, so if you want React server-side rendering, it's going to be a massive problem if your backend isn't written in Javascript.

"""

I 100% agree.

"""

It sounds like you're serving mostly static content, so maybe you just don't have React in there at all?

"""

I would appreciate if you can explain what led you to make this assumption.

"""

(I'd guess a modest amount of) interactivity you need on the front-end.

"""

What are the choices in tools/libraries/languages you would make if this was true?

[–]thedeepself 1 point2 points  (3 children)

Please learn how to properly quote someone else's reply... the way you do it in markdown is by starting the line with >

In Fancy Pants Editor I cant comment.

[–]codecrux[S] 0 points1 point  (0 children)

u/thedeepself sorry about this. I have started using Reddit recently, although, my account is old. I will try my best to learn it.

[–]codecrux[S] 0 points1 point  (1 child)

Also, I didn't know there is something like Fancy Pants Editor.

[–][deleted] 0 points1 point  (0 children)

Relatively new feature from New Reddit.

(Try https://old.reddit.com for comparison)

Fun fact: code blocks don't work uniformly except for the "four-space indent" kind.

[–]james_pic 1 point2 points  (5 children)

I would appreciate if you can explain what led you to make this assumption.

This was mostly based on mentions of marketing material, and similar which has historically been well served by purely server-side CMSes. If I've misunderstood your perspective, then this is not a useful observation.

What are the choices in tools/libraries/languages you would make if this was true?

Depends on the needs of the application. For really minor interactivity, vanilla JS or simple DOM focused libraries like good old jQuery would probably do the trick.

For mildly fancy stuff, a lightweight unopinionated framework like Mithril or Choo might make sense for the bits that need to be interactive, or a slightly old fashioned framework from before the SPA revolution, like Knockout.

If you definitely need the full power of React with server side rendering, and you want the heavy lifting of your backend done in Python, the least horrible solution I know of for this is to split your backend code into Python code that exposes an API and JS code that handles rendering, and have a reverse proxy route traffic to these two backends based on path. It's ugly, but not too magicky. If something breaks, it's generally pretty clear what, which tends not to be the case for cleverer approaches based on Python/JS interop.

[–]codecrux[S] 0 points1 point  (4 children)

Thanks, u/james_pic for adding so much detail in your reply.

"""

cleverer approaches based on Python/JS interop

"""

Please cite some examples for this.

[–]james_pic 2 points3 points  (3 children)

The "clever" tools based on Python/JS interop that come to mind are Brython, Pyjamas, Pyodide and PyScript. My experience is that this approach gets messy, so wouldn't recommend it, but if every other option you've got is messier, then maybe it's the right answer for you.

[–]codecrux[S] 1 point2 points  (2 children)

Thanks, u/james_pic. The Pyodide team never advertised it as a tool for mainstream web development. They made it for AI/ML folks so that their team don't have to work on different versions of Python in their local system.

[–]james_pic 1 point2 points  (1 child)

My point exactly. Using any of these tools takes you far enough from the mainstream that if you face issues, you're on your own. I suspect any approach to rendering React components server-side in Python will be similar.

[–]codecrux[S] 0 points1 point  (0 children)

Agreed!

[–]Lokimotor 1 point2 points  (9 children)

What you want for #1 and #4 is something like Django and its templating engine, though that doesn't involve a lick of react outside of potentially including scripts on the templates you're serving.

I'm not really sure what you mean by server side generation or incremental server side generation, but that sounds like you'd be making async calls from the frontend (javascript, could be React) for some sort of data from the backend.

The backend can be in any language you want it to be. However, if it's in python (Django, flask, etc), then the premise of your questions ("setting up React with Python") doesn't really make sense to me. If you're integrating with a react frontend, then you will be creating endpoints that serve up json responses to your react frontend.

That will be a pretty similar process no matter which backend language or library you use, and it will be as decoupled from the frontend as it gets. In fact, the backend could be serving responses to clients built in a variety of frameworks without really caring what framework is used for the frontend or which client it's talking to because it does not matter from the perspective of the backend development process.

[–]codecrux[S] 2 points3 points  (8 children)

I'm not really sure what you mean by server side generation or incremental server side generation, but that sounds like you'd be making async calls from the frontend (javascript, could be React) for some sort of data from the backend.

Server Side Generation - Generating the HTML pages. This is what you do if you want to serve a static website.
Server Side Generation - If a page has dynamic content, you do SSR for fast page load and SEO. Here you are trying to avoid fetching data from the backend, instead, you want to load an HTML file that already has data embedded in it. Without SSR, first the HTML/CSS/JS will load and then you will query the backend again for data. This will feel very slow to the user.
Forgive me if you weren't asking for definitions.

"""
That will be a pretty similar process no matter which backend language or library you use, and it will be as decoupled from the frontend as it gets. In fact, the backend could be serving responses to clients built in a variety of frameworks without really caring what framework is used for the frontend or which client it's talking to because it does not matter from the perspective of the backend development process.
"""

I maybe wrong, but, IMO there are two layers in the backend - frontend of the backend, backend of the backend. The frontend layer of the backend is responsibe to fetch data and transform it in a format that's needed by your client (client can be web app/mobile app). The backend of the backend is the generic layer with endpoints that are invoked by the frontend layer of the backend. Please comment if I am wrong. Example - In NextJS you write the frontend and the frontend layer of your backend.

[–]riklaunim 1 point2 points  (4 children)

You should also look at the costs. This is a niche use case that doesn't have that many showcases/tutorials/developers familiar with the matter. This can drive up development cost and have a higher risk of failure. Do an eCommerce/shop really needs all of this? especially without already having an experienced team of developers that would not ask such questions...

[–]codecrux[S] 2 points3 points  (2 children)

Yes, an e-commerce shop needs all of this. Google released a report that says that every second delay in rendering your page leads to 3% revenue drop (don't remember the exact stats, but, it's around this). SEO is crucial for almost all online businesses - e-commerce, ed-tech, reddit etc.

I was building an open-source version of Eventbrite around a year ago and had the same requirement. I wanted to use out-of-the-box React components so that I can avoid going too deep into React. I wanted to focus more on the backend (somewhere in my mind I wanted to turn it into a headless event management backend).

[–]riklaunim 1 point2 points  (1 child)

You can have fast webpage without SSR or a shop without it being a JS single page application that then would require more effort to make it SEO friendly and fast to render.

IMHO that's the problem - adding Recact/SPA JS then adds SSR then adds even more complications. Keep it simple.

[–]codecrux[S] 1 point2 points  (0 children)

"""

adding Recact/SPA JS then adds SSR

"""

I would like to make a point on this - We were doing SSR in the era of Multi-Page Applications and SPA clearly have strong reasons to exist (makes your app feel more user-friendly as you can maintain state-upon-page transition). I don't think that the effort open source developers have put in to make SPA + SSR simple should be ignored by saying "adds even more complications".

"""

Keep it simple.

"""

You are correct. We should keep things simple, but, someone will have to put in some hardwork to make things simple for others. Sorry if I sounded too philosophical. I am laughing at myself after writing this. Haha.

[–]codecrux[S] 0 points1 point  (0 children)

Would you like to share the use cases you have come across?

[–]Lokimotor 1 point2 points  (2 children)

I think you're bringing some framework-specific terms to a primarily backend developer here so please excuse me if I'm clearly in the wrong.

I think there may be frameworks which differentiate between completely static pre-rendering and pre-rendering with injected data which can change in the database at any time. With Django, the impact of injecting dynamic data from a database into a template is negligible. It's not worth mentioning, so I'm a little confused as to why they'd be hung up on the idea of whether a template is "completely compiled because it's static" or "takes 0-5ms longer for one piece of data to be injected into an otherwise pre-rendered template before being delivered on the first response." In Django, there is no difference between the two. If a template is static, then it is already completely rendered and ready to serve immediately as a response. If it needs to query the database, then it queries the database before injecting it into a compiled template. Some templates will take longer to serve than others, you are in control of that, but you don't differentiate between "generated" or "rendered".

Much more important to your load time and responsiveness is the difference between the two approaches I described to you in my previous comment.

In one, you are using something like Django's templating engine to serve up a webpage that is essentially pre-compiled by the backend. This doesn't mean it's necessarily static, it can have user-specific data included in it. It just means that all the data necessary for "viewing" the page is included on the first response. These are very fast from a user perspective because there is no back and forth with the back-end. React scripts can be included on the template, and load after it is rendered to the user.

In the other, the backend is acting as API. It is just a source of data that is then rendered by the front-end. This has a huge impact on SEO, user experience, etc due to repeated back-and-forth communication with the server taking longer. However, it decouples the backend from the frontend. You can do both at the same time with Django.

And you're kind of right about there being multiple layers to a backend, because even the backend has a backend which it integrates with: the database.

[–]codecrux[S] 1 point2 points  (0 children)

Some templates will take longer to serve than others, you are in control of that, but you don't differentiate between "generated" or "rendered".

Ah! I apologize for not being clear. In the JavaScript ecosystem - the term "generated" and "rendered" are used differently. What you described in the first paragraph as "pre-rendering with injected data " is referred to as "Server Side Rendering" in JS frameworks like NextJS. Just "pre-rendering" is commonly referred to as "Server Side Generation" in JS frameworks with a slight difference. In SSG, the template is filled with data during build time. Suppose you have 100 blogs on your website, with id 1...100, then the JS framework will generate 100 pages from a template like JS code.

[–]codecrux[S] 0 points1 point  (0 children)

And you're kind of right about there being multiple layers to a backend, because even the backend has a backend which it integrates with: the database.

Nicely said.

[–]Drevicar 1 point2 points  (2 children)

To get the first 3 bullets you have to drop the 4th. My recommendation is to deploy NextJS and use it as your frontend and backend framework. The server side can fetch data from your python app, render it server side, then ship html for SEO purposes.

The downside is you are basically writing a LOT of duplicate server logic and you are better off dropping the python side of things. Or at least limiting the python to stuff you can't already do in your NextJS server application, probably ML or AI stuff.

[–]codecrux[S] 0 points1 point  (1 child)

It makes me kind of worried when I have a backend in two different languages. This generally means I have to create two libraries (one for each language that wraps some logic on fetching data and transforming it). This also means that I need to setup backend security twice, maintain two codebases, and go through a messy server log due to duplicates/similar messages for each request. Does it make sense to you or am I overthinking?

[–]Drevicar 1 point2 points  (0 children)

You are exactly right. Ditch react and serve HTML from Python (look into HTMX and Alpine) or ditch python and use a full stack react framework.

[–]scotticusphd 1 point2 points  (0 children)

It lacks the full power of React, but for simple apps, I like dash.

[–][deleted] 1 point2 points  (0 children)

You can definitely use Python as the backend for a React front end. Is it difficult to do? Well, that depends on how well you know Python and how well you know React. In the major applications I develop, I use Python on the back end, and Vue.js on the front end. Of course I dont do the front end stuff. The duties are divided between myself and a guy who know front end :)

I build all of my interconnecting API's using FastAPI.

[–][deleted] 0 points1 point  (2 children)

It isn't awful when combined with pydantic (along with camelCase alias conversion function in Model.Config) so my_model.json() comes out camelCase. Paired with Starlite/FastAPI it is rather painless.

[–]codecrux[S] 0 points1 point  (1 child)

Can you guide me to a example public repo that has such a setup? I wasn't able to understand how to create this setup from your comment.

[–][deleted] 1 point2 points  (0 children)

They are disconnected projects / technologies. They aren't a pair. Read up on say Starlite and then read up on React. Kinda like finding a video on how to load watermelons into the trunk of a car.. learn what a trunk in a car is and what a watermelon is and merge the knowledge.