About: Web Developer, Freelance Technical Writer, always eager to learn new technologies
Location:
West Bengal, India
Joined:
Feb 25, 2024
Intro to PYJSX
Publish Date: Jul 13
33 20
Did you know that you can write JSX in python code?
Yes, I am not kidding! It is actually possible today!
You may have found jinja templates ugly and absolutely nightmare for templating in django or flask. If that's so, you are really going to enjoy this quick tutorial.
In this article, I am going to show you an interesting approach to component driven frontend development in python using a new library which is called pyjsx.
So, let's get started!
Set up the Virtual Environment
First things first. Let's quickly set up a venv to install the required library.
If you use mypy then set up the ini file (mypy.ini) for accurate type checking.
[mypy]plugins=pyjsx.mypy
Now we are ready to dive in.
Note: I am not going to install flask or quart or hypercorn or any other dedicated backend framework or http server library, for this simple pyjsx demonstration.
We will use the http.server module from the standard library of python for setting up the web server.
Let's Write some Python JSX (PYJSX)
Just exactly how you write functional components and pass props to them in React you do it the same way in pyjsx.
for example, you would write a header component this way -
The most important things here to know and be careful about are -
The comment # coding: jsx is REQUIRED. It is not a plain regular comment but a directive that tells Python to let our library parse the file first.
The components can't be defined in a regular python file. You are only allowed to import the components in a python file, from the parsed files that contain the component definition(s). This component filename must end with .px file extension.
The import from pyjsx import jsx is vital because PyJSX transpiles JSX into jsx(...) calls so it must be in scope.
Let's define some components
Make sure you put the file extension as .pxNOT.py.
Now, Here comes the part of server. We will set up a pretty simple http server to serve the <App/> component on GET request.
Hey, hey, hey, before writing a runnable file, remember this -
❗❗ To run a file containing JSX, the jsx codec must be registered first in the runtime, which can only be done with from pyjsx import auto_setup.
⚠️ This must occur before importing px files or any other file containing JSX.
Setting Up the server
Import modules -
fromhttp.serverimportBaseHTTPRequestHandler,HTTPServerfrompyjsximportauto_setup# MUST import this before importing JSX
fromappimportApp
Define constants -
HOST='127.0.0.1'PORT=8080
Define the HTTP request handler class to setup server
classMyHandler(BaseHTTPRequestHandler):defdo_GET(self):self.send_response(200)# Send response headers
self.send_header('Content-type','text/html')self.end_headers()# using fstring to convert the JSX into string
response=f"{App()}"# convert the string data into bytes before sending over network
self.wfile.write(response.encode())deflog_message(self,format,*args):return# Suppress default logging for clean output
defrun_server():server=HTTPServer((HOST,PORT),MyHandler)print(f"Serving HTTP on {HOST}:{PORT} ...")try:server.serve_forever()exceptKeyboardInterrupt:print("\nShutting down the server.")server.server_close()
Now let's run the server to see it in action (I mean browser).
Look, our server works perfectly fine, and the pyjsx code is beautifully rendered in the DOM!
Look at the browser console -
Wrapping it up
You must be delighted to know that pyjsx also supports fragment components <></> and nested expressions like -
<div>{[<p>Row:{i}</p>foriinrange(10)]}</div>
already.
So, we see that pyjsx has a lot of potential.
It is a new library, and I think it is not ready for production yet. But it is completely open source with Apache Licence, so with valuable community contributions we can make development of this library progress rapidly and see it as a huge leap forward towards declarative web ui development in python.
What do you think, want to give it a go?
Check it out in GitHub and explore more examples to build something awesome with it!
I would really appreciate your feedback on this tutorial. How would you rate it? How can I improve it?
If you found this project or tutorial helpful, please consider sharing some love to the article. It will encourage me to create more content like this.
If you found this POST helpful, if this blog added some value to your time and energy, please support by sharing it with your developer friends.
Well actually Jinja really serves its purpose greatly. That being said, it is a templating engine for python.
Jinja is generally static, (HTML rendered before delivery). While JSX is dynamic and is loved by devs mostly for its component-based reusability, nesting and the ability of easily passing props for dynamic behavior.
The best way is to use the best of both worlds.
As in the end, we are converting PyJSX into strings currently for rendering as html, we will be able to use them directly in flask routes. What we can do is break our whole UI into reusable components and then serve them as html when sending via response in flask routes.
A Quick Example for you if my explanation above was messy (sorry 🥲😅😅🥲) -
PyJSX with Flask
With PyJSX, you define your components in Python files (often with a .px extension, though not strictly required for simple cases if transpiled correctly). The output of a PyJSX component is of JSX type which can be formatted in fstrings, which Flask can directly return.
First, define a PyJSX component. You would typically save this in a file, for example, component.px -
Then, in your Flask application (app.py), you would import and use these components:
fromflaskimportFlaskfrompyjsximportauto_setupfromcomponentimportHomePageapp=Flask(__name__)@app.route('/')defhome_pyjsx():# Render the PyJSX component to a string
rendered_html=HomePage(user_name="KOmSenpati",items=["Pen","Paper","Laptop"])print(rendered_html)returnf'{rendered_html}',{'Content-Type':'text/html'}if__name__=='__main__':app.run()
No, I am even fine with people breaking established industry standards, I get it, it is fun. I just don't like it when people take the joke too seriously and actually start using these in production. Look what happened to React. They invent a new "solution" to the mess they helped create every year, and each solution requires two new inventions.
If you hold your ear from the other side so often that your arms get entangled, you should just let go.
I've recently been using python for devops automation with aws. Its faster than using bash aws cli (though bash is still essential for provisioning ec2 setup, along with Docker). Its twice as fast as using nodejs for file automation. What it sucks on is type integration. Even with pydantic, flake8 and black formatter, typescript is three times faster and intellisense is fast. Python has its place but in comparison to nodejs, vite, react is all over it. I don't even have to worry about indentation.
Conclusion:
Jsx for python is like trying to write semantic html in an svg text tag. Pardon my English - Crap.
Insightful