Giter VIP home page Giter VIP logo

python-react's Introduction

python-react

Build Status

Server-side rendering of React components with data from your Python system

from react.render import render_component

rendered = render_component(
    '/path/to/component.jsx',
    {
        'foo': 'bar',
        'woz': [1,2,3],
    }
)

print(rendered)

For client-side integrations, refer to the docs.

Documentation

Installation

pip install react

Basic usage

python-react provides an interface to a render server which is capable of rendering React components with data from your python process.

Render requests should provide a path to a JS file that exports a React component. If you want to pass data to the component, you can optionally provide a second argument that will be used as the component's props property.

from react.render import render_component

rendered = render_component('path/to/component.jsx', {'foo': 'bar'})

print(rendered)

The object returned has three properties:

  • markup - the rendered markup
  • props - the JSON-serialized props
  • data - the data returned by the render server

If the object is coerced to a string, it will emit the value of the markup attribute.

Setting up a render server

Render servers are typically Node.js processes which sit alongside the python process and respond to network requests.

To add a render server to your project, you can refer to the basic rendering example for a simple server that will cover most cases. The key files for the render server are:

Using React on the front-end

There are a number of ways in which you can integrate React into the frontend of a Python system. The typical setup involves a build tool and a python package that can integrate it.

The two most popular build tools are:

  • Webpack - compiles your files into browser-executable code and provides a variety of tools and processes which can simplify complicated workflows.
  • Browserify - has a lot of cross-over with webpack. Is argurably the easiest of the two to use, but it tends to lag behind webpack in functionality.

For React projects, you'll find that webpack is the usual recommendation. Webpack's hot module replacement, code-splitting, and a wealth of loaders are the features typically cited as being irreplaceable. react-hot-loader is a particularly useful tool, as it allows changes to your components to be streamed live into your browser.

If you want to integrate webpack's output into your python system, you can either hard-code the paths or you can use a manifest plugin that provides a way for your python system to introspect the compiler's state.

The most popular manifest tool is owais/django-webpack-loader. Owais has provided a great set of docs and examples, so it's your best bet for integrating webpack into your project.

If you aren't running a Django system, or you need portable manifests that can be decoupled and deployed, markfinger/python-webpack-manifest might suit your needs.

There's also markfinger/python-webpack, but it's a bit more heavy handed, abstract, and is only of use if you need a really tight coupling between your python and javascript worlds.

render_component

Renders a component to its initial HTML. You can use this method to generate HTML on the server and send the markup down on the initial request for faster page loads and to allow search engines to crawl your pages for SEO purposes.

Usage

from react.render import render_component

render_component(
    # A path to a file which exports your React component
    path='...',

    # An optional dictionary of data that will be passed to the renderer
    # and can be reused on the client-side.
    props={
        'foo': 'bar'
    },

    # An optional boolean indicating that React's `renderToStaticMarkup` method
    # should be used, rather than `renderToString`
    to_static_markup=False,

    # An optional object which will be used instead of the default renderer
    renderer=None,

    # An optional dictionary of request header information (such as `Accept-Language`)
    # to pass along with the request to the render server
    request_headers={
        'Accept-Language': 'da, en-gb;q=0.8, en;q=0.7'
    },

    # An optional timeout that is used when handling communications with the render server.
    # Can be an integer, a float, or a tuple containing two numeric values (the two values
    # represent the individual timeouts on the send & receive phases of the request).
    # Note that if not defined, this value will default to (5, 5)
    timeout=None
)

If you are using python-react in a Django project, relative paths to components will be resolved via Django's static file finders.

By default, render_component relies on access to a render server that exposes an endpoint compatible with react-render's API. If you want to use a different renderer, pass in an object as the renderer arg. The object should expose a render method which accepts the path, data, to_static_markup, and request_headers arguments.

Render server

Earlier versions of this library would run the render server as a subprocess, this tended to make development easier, but introduced instabilities and opaque behaviour. To avoid these issues python-react now relies on externally managed process. While managing extra processes can add more overhead initially, it avoids pain down the track.

If you only want to run the render server in particular environments, change the RENDER setting to False. When RENDER is False, the render server is not used directly, but it's wrapper will return similar objects with the markup attribute as an empty string.

Usage in development

In development environments, it can be easiest to set the RENDER setting to False. This ensures that the render server will not be used, hence you only need to manage your python process.

Be aware that the render servers provided in the examples and elsewhere rely on Node.js's module system which - similarly to Python - caches all modules as soon as they are imported. If you use the render server in a development environment, your code is cached and your changes will not effect the rendered markup until you reset the render server.

Usage in production

In production environments, you should ensure that RENDER is set to True.

You will want to run the render server under whatever supervisor process suits your need. Depending on your setup, you may need to change the RENDER_URL setting to reflect your environment.

The render server should be run with the NODE_ENV environment variable set to production, eg: NODE_ENV=production node render_server.js. React defaults to development mode and relies on the NODE_ENV variable to deactivate dev-oriented code (types and constraint checking) that slows down renders. Defining this variable will ensure that your code is rendered much faster.

Depending on your load, you may want to use a worker farm to handle rendering. Node's cluster module provides an easy way to fork a process and serve multiple instances from a single network address.

An alternative to worker farms is to put a cache in front of the render server. Be aware that render server requests are sent as POST requests and most reverse proxies have issues with caching POST requests.

When the render server wrapper connects to the JS process, it adds a ?hash=... parameter to the url. The hash parameter is a SHA-1 hash of the serialized data that is sent in the request's body and is intended for consumption by caching layers.

Another alternative is to wire the calls to the render server into your caching system. If you override the renderer kwarg, you could wrap the call to the server to first check if the data is available locally and fallback to populating the cache with the rendered markup.

Overriding the renderer

If you want to override the default renderer, one approach is to create a wrapper function so that you can consistently define the renderer argument to render_component. For example:

from react.render import render_component

class MyRenderer(object):
    def render(self, path, props=None, to_static_markup=False, request_headers=None, timeout=None):
        # ...

def my_render_function(*args, **kwargs):
    kwargs['renderer'] = MyRenderer()
    return render_component(*args, **kwargs)

Settings

If you are using python-react in a non-django project, settings can be defined by calling react.conf.settings.configure with keyword arguments matching the setting that you want to define. For example:

from react.conf import settings

DEBUG = True

settings.configure(
    RENDER=not DEBUG,
    RENDER_URL='http://127.0.0.1:9009/render',
)

If you are using python-react in a Django project, add 'react' to your INSTALLED_APPS and define settings in a REACT dictionary.

INSTALLED_APPS = (
    # ...
    'react',
)

REACT = {
    'RENDER': not DEBUG,
    'RENDER_URL': 'http://127.0.0.1:8001/render',
}

RENDER

A flag denoting that the render server should be used. If set to False, the renderer will return objects with an empty string as the markup attribute.

Pre-rendering your components is only intended for environments where serving markup quickly is a must. In a live development environment, running multiple processes overly complicates your setup and can lead to inexplicable behaviour due to the render server's file caches. Setting this to False will remove the need to run a render server next to your python server.

Default: True

RENDER_URL

A complete url to an endpoint which accepts POST requests conforming to react-render's API.

Default: 'http://127.0.0.1:9009/render'

Frequently Asked Questions

How do I return extra data from the render server?

You can edit the render server's code and annotate the returned payload with whatever data that you like. The payload provided by the render server is available under the data attribute of the response object.

For example:

from react.render import render_component

rendered = render_component('path/to/component.js')

print(rendered.data)

Can python-react integrate with Django?

python-react can integrate with Django's settings and the renderer integration can resolve relative paths to components via django's static file finders.

How do I handle Django's translation and gettext with React components?

sillygod sparked a discussion of this at issue #69.

Can python-react integrate with Web2Py?

Anima-t3d has a write-up of their experience in #70.

How do I pass child components to the root component?

Anima-t3d sparked a discussion of this at issue #71.

Running the tests

pip install -r requirements.txt
npm install
python runtests.py

python-react's People

Contributors

abdelouahabb avatar anantzoid avatar benateventbrite avatar benmvp avatar cburmeister avatar defrex avatar eb-emilio avatar gravybrux avatar jchen-eb avatar lolivera-eb avatar markfinger avatar matthewryanscott avatar mic159 avatar mplis avatar pirate avatar pringels avatar runejuhl avatar sassanh avatar timgates42 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-react's Issues

How to setup with react-hotloader?

hotloader makes developer much faster, but it's not clear how to set it up with python-react as python-webpack seems to have its own way of checking for file changes. I know how to set it up with a normal webpack setup, but since python-webpack works differently I am not sure how to make this work.

I would love some documentation about this? Thanks!

Combining server side rendering with client side

Hi, I am trying to follow both the Flask and the Tornado examples to convert a client side React component to render on the server side but still be able to trigger the life cycle methods such as componentDidMount on the client side. So far I haven't been able to figure it out.

componentWillMount fires on the server side but componentDidMount doesn't fire on the client side. I even added the browser check like this to the jsx (based on this article):

if (isNode) {
  exports.TrailApp = TrailApp
} else {
  ReactDOM.render(<TrailApp />, document.getElementById('content'))
}

Is there anything I am missing on the server side?

Thanks
-Selim

Render Server in watch mode

Hi,
Currently, one needs to restart the render_server.js (taken from the examples) everytime any change is made in a component. You have mentioned that resetting the server is required in developement mode, but do you think there's any way if the node server could watch these changes. I tried to find a solution, but still struggling. Constantly restarting the node server during development becomes quite tedious.
Thanks.

Possible to integrate with React Router?

I'm not that familiar with Webpack yet, but would it be possible to use React Router somehow?

Like:

  • User opens domain.com/signup/ --> django pre-renders JSX
  • User signs-up, route transitions to /app - no page refresh required

What would I put to react router's route handlers? "jsx__Signup" or equivalent?

Thanks!

Type Error

Hi Mark,
Just clone this repo and I am getting a type error as follwoing for both "translate and bundle":

render_component() got an unexpected keyword argument 'translate'

What I am doing wrong :(

Compatible with React 0.14?

Hi! I think there may be a compatibility issue with React 0.14. I cant seem to get this library working for server side rendering in Python.

example not working

I tried to run the example in a virtualenv 'test' but I get an error message:
(test)MfM@MfM-XPS:~/TEST/python-react-master/example$ python3 example.pyTraceback (most recent call last):
File "example.py", line 4, in
from settings import DEBUG, BASE_DIR
File "/home/MfM/TEST/python-react-master/example/settings.py", line 11, in
USE_MANAGER=DEBUG
File "/usr/local/lib/python3.4/dist-packages/js_host/conf.py", line 60, in configure
from .host import host
File "/usr/local/lib/python3.4/dist-packages/js_host/host.py", line 13, in
status = read_status_from_config_file(config_file)
File "/usr/local/lib/python3.4/dist-packages/js_host/bin.py", line 31, in read_status_from_config_file
return json.loads(stdout)
File "/usr/lib/python3.4/json/init.py", line 318, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.4/json/decoder.py", line 343, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.4/json/decoder.py", line 361, in raw_decode
raise ValueError(errmsg("Expecting value", s, err.value)) from None
ValueError: Expecting value: line 1 column 1 (char 0)

Design question (React-router, Redux)

Hi there,

I was wondering if you had any experience with react-router and redux together for server-side rendering.
I know about HorizonXP/react-router-render, (which would need an update to react-router 1.x), but to use Redux I would need to wrap my component/routes into <Provider> (with the initial data that I must also provide somehow).

Is there any way we can make this work with python-react/react-render?

Related:
https://github.com/rackt/react-router/blob/master/docs/guides/advanced/ServerRendering.md
http://rackt.org/redux/docs/recipes/ServerRendering.html#async-state-fetching

some trouble with Express 4

I have some problem to run the last build of django_react with express 4. The source of the problem seems to come from render.js. django_node send post request and thus request.query.var return nothing. To solve it, i changed every occurence of request.query.--- to request.body.--- in the "var service = function(request, response)" of render.js. Have a nice day !

Request for a django example using python-react and python-webpack

This isn't an issue so much as it is a request. I had everything working with python-react but then I upgraded the package and now I'm struggling really bad to get it working again. The server side rendering is working but nothing is interactive. So I've been trying to get python-webpack working but it's throwing fun errors like "Unexpected response from http://127.0.0.1:9009/build - 404: Cannot POST /build" and I have no idea how to even go about debugging. I'm brand new to webpack and fairly new to most frontend development in general so if you have time to throw together an example that puts the two packages together I would be extremely grateful.

Thank you!

test gives error

When I run the test, I get:

(test3.4.3) MfM@MfM-XPS:~/TEST/python-react-master$ python runtests.py


Running tests without django

E

ERROR: Failure: ConfigError (js-host binary /home/MfM/TEST/python-react-master/tests/node_modules/js-host/bin/js-host.js does not exist)

Traceback (most recent call last):
File "/home/MfM/.pyenv/versions/test3.4.3/lib/python3.4/site-packages/nose/failure.py", line 39, in runTest
raise self.exc_val.with_traceback(self.tb)
File "/home/MfM/.pyenv/versions/test3.4.3/lib/python3.4/site-packages/nose/loader.py", line 420, in loadTestsFromName
addr.filename, addr.module)
File "/home/MfM/.pyenv/versions/test3.4.3/lib/python3.4/site-packages/nose/importer.py", line 47, in importFromPath
return self.importFromDir(dir_path, fqname)
File "/home/MfM/.pyenv/versions/test3.4.3/lib/python3.4/site-packages/nose/importer.py", line 94, in importFromDir
mod = load_module(part_fqname, fh, filename, desc)
File "/home/MfM/.pyenv/versions/3.4.3/lib/python3.4/imp.py", line 245, in load_module
return load_package(name, filename)
File "/home/MfM/.pyenv/versions/3.4.3/lib/python3.4/imp.py", line 217, in load_package
return methods.load()
File "", line 1220, in load
File "", line 1200, in _load_unlocked
File "", line 1129, in _exec
File "", line 1471, in exec_module
File "", line 321, in _call_with_frames_removed
File "/home/MfM/TEST/python-react-master/tests/init.py", line 8, in
js_host.conf.settings.configure(**JS_HOST)
File "/home/MfM/.pyenv/versions/test3.4.3/lib/python3.4/site-packages/js_host/conf.py", line 60, in configure
from .host import host
File "/home/MfM/.pyenv/versions/test3.4.3/lib/python3.4/site-packages/js_host/host.py", line 13, in
status = read_status_from_config_file(config_file)
File "/home/MfM/.pyenv/versions/test3.4.3/lib/python3.4/site-packages/js_host/bin.py", line 16, in read_status_from_config_file
cmd = (settings.PATH_TO_NODE, settings.get_path_to_bin(), config_file, '--config',)
File "/home/MfM/.pyenv/versions/test3.4.3/lib/python3.4/site-packages/js_host/conf.py", line 94, in get_path_to_bin
raise ConfigError('js-host binary {} does not exist'.format(path))
js_host.exceptions.ConfigError: js-host binary /home/MfM/TEST/python-react-master/tests/node_modules/js-host/bin/js-host.js does not exist


Ran 1 test in 0.038s

FAILED (errors=1)


Running tests with django

Traceback (most recent call last):
File "runtests.py", line 19, in
django.setup()
File "/home/MfM/.pyenv/versions/test3.4.3/lib/python3.4/site-packages/django/init.py", line 18, in setup
apps.populate(settings.INSTALLED_APPS)
File "/home/MfM/.pyenv/versions/test3.4.3/lib/python3.4/site-packages/django/apps/registry.py", line 108, in populate
app_config.import_models(all_models)
File "/home/MfM/.pyenv/versions/test3.4.3/lib/python3.4/site-packages/django/apps/config.py", line 198, in import_models
self.models_module = import_module(models_module_name)
File "/home/MfM/.pyenv/versions/3.4.3/lib/python3.4/importlib/init.py", line 109, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "", line 2254, in _gcd_import
File "", line 2237, in _find_and_load
File "", line 2226, in _find_and_load_unlocked
File "", line 1200, in _load_unlocked
File "", line 1129, in _exec
File "", line 1471, in exec_module
File "", line 321, in _call_with_frames_removed
File "/home/MfM/.pyenv/versions/test3.4.3/lib/python3.4/site-packages/js_host/models.py", line 7, in
**getattr(settings, 'JS_HOST', {})
File "/home/MfM/.pyenv/versions/test3.4.3/lib/python3.4/site-packages/js_host/conf.py", line 60, in configure
from .host import host
File "/home/MfM/.pyenv/versions/test3.4.3/lib/python3.4/site-packages/js_host/host.py", line 13, in
status = read_status_from_config_file(config_file)
File "/home/MfM/.pyenv/versions/test3.4.3/lib/python3.4/site-packages/js_host/bin.py", line 16, in read_status_from_config_file
cmd = (settings.PATH_TO_NODE, settings.get_path_to_bin(), config_file, '--config',)
File "/home/MfM/.pyenv/versions/test3.4.3/lib/python3.4/site-packages/js_host/conf.py", line 94, in get_path_to_bin
raise ConfigError('js-host binary {} does not exist'.format(path))
js_host.exceptions.ConfigError: js-host binary /home/MfM/TEST/python-react-master/tests/node_modules/js-host/bin/js-host.js does not exist

Could you add a bit of info to the docs about costs and benefits?

I'll dig around and figure this out myself but it would be useful to add some more info on the following to the docs:

  1. Does it launch and initialise node or v8 on every render call? What's the performance like?
  2. If yes to (1) - is there a way to connect to an existing persistent node server to reduce this?
  3. Is there any internal caching? If not what's the recommended way to use Django's caching with django-react?

Unexpected token error

Here is the error

Stack trace: SyntaxError: /home/junaid/work/savemyscope/frontend/js/app/containers/home.jsx: Unexpected token (83:12)
  81 |     render() {
  82 |         return (
> 83 |             <div>
     |             ^
  84 |                 <NavBar
  85 |                     navClass={this.state.navClass}
  86 |                     logo={this.state.logo}
    at Parser.pp.raise (/home/junaid/work/savemyscope/node_modules/babylon/lib/parser/location.js:22:13)
    at Parser.pp.unexpected (/home/junaid/work/savemyscope/node_modules/babylon/lib/parser/util.js:89:8)
    at Parser.pp.parseExprAtom (/home/junaid/work/savemyscope/node_modules/babylon/lib/parser/expression.js:517:12)
    at Parser.pp.parseExprSubscripts (/home/junaid/work/savemyscope/node_modules/babylon/lib/parser/expression.js:272:19)
    at Parser.pp.parseMaybeUnary (/home/junaid/work/savemyscope/node_modules/babylon/lib/parser/expression.js:252:19)
    at Parser.pp.parseExprOps (/home/junaid/work/savemyscope/node_modules/babylon/lib/parser/expression.js:183:19)
    at Parser.pp.parseMaybeConditional (/home/junaid/work/savemyscope/node_modules/babylon/lib/parser/expression.js:165:19)
    at Parser.pp.parseMaybeAssign (/home/junaid/work/savemyscope/node_modules/babylon/lib/parser/expression.js:128:19)
    at Parser.pp.parseParenAndDistinguishExpression (/home/junaid/work/savemyscope/node_modules/babylon/lib/parser/expression.js:590:26)
    at Parser.pp.parseExprAtom (/home/junaid/work/savemyscope/node_modules/babylon/lib/parser/expression.js:476:19)
    at Parser.pp.parseExprSubscripts (/home/junaid/work/savemyscope/node_modules/babylon/lib/parser/expression.js:272:19)
    at Parser.pp.parseMaybeUnary (/home/junaid/work/savemyscope/node_modules/babylon/lib/parser/expression.js:252:19)
    at Parser.pp.parseExprOps (/home/junaid/work/savemyscope/node_modules/babylon/lib/parser/expression.js:183:19)
    at Parser.pp.parseMaybeConditional (/home/junaid/work/savemyscope/node_modules/babylon/lib/parser/expression.js:165:19)
    at Parser.pp.parseMaybeAssign (/home/junaid/work/savemyscope/node_modules/babylon/lib/parser/expression.js:128:19)
    at Parser.pp.parseExpression (/home/junaid/work/savemyscope/node_modules/babylon/lib/parser/expression.js:92:19)

And here is my views.py

from django.shortcuts import render
from react.render import render_component


def index(request):
    rendered = render_component('js/app/containers/home.jsx', {}, to_static_markup=True)
    print(rendered)
    return render(request, 'pages/rendered_index.html', {})

I don't know what going wrong here.

Issue with _PROXY_DJANGO_SETTINGS?

The docs say that I can add settings for RENDER & RENDER_URL, but it's not working. I've traced it down to conf.py and the _PROXY_DJANGO_SETTINGS private variable.

It's initialized to False, but there's no way to to set it True. So in RENDER_URL & RENDER it always returns the default settings _render_url & _render.

My current workaround is to call configure directly so that I can override the defaults:

from react import conf
from django.conf import settings
conf.settings.configure(settings.REACT.get('RENDER_URL'), settings.REACT.get('RENDER'))

...but this seems wrong. Am I missing something?

Thanks for the library BTW!

.babelrc not configured correctly in project example

In the basic rendering example the provided .jsx files make use of es6 syntax.
However the .babelrc configuration does not include an es6 compiler plugin.

I propose adding "presets": ["es2015"] to the config.

How the diff will work in python?

Hi,
sorry for this question, this is the first time I try the react serverside rendering, and when trying to debug, i dident found the react traces (the result is in of course), I downloaded an example here https://github.com/mhart/react-server-example and I can see the react traces, si the diff algorithm could work at the client, here is two screenshots:

this is with:

with

without (hello world)

noreact

Omit 'react/addons' from the generated bundle

Similarly to 'react', the one difference is that 'react/addons' exports React with an addons prop.

On the server-side it should map to 'react/addons', but on the client-side it should map to 'React'.

pyramid-react

I'm not sure how feasible this would be but it would be nice if this was generalized to work on Pyramid too.

Having trouble with django integration

The first time I try to render_component I get a BundlingError, and then subsequent attempts to render the same component result in a FunctionTimeout.

I followed all the instructions, first installing js-host and python-webpack (following each of their instructions), and then python-react but I am unable to get this to work with django. To avoid any possibility of it being something specific to the project I'm working on, I tried to get it working again in a fresh Django project but to no avail. I pushed that one to github in case it's helpful: https://github.com/krisfields/pythonreacttest

Could you take a look at the traceback below (and/or the github project) and see if you might be able to ascertain where I may have went wrong?

(pythonreacttest)Poor-Mans-Delegate:pythonreacttest avalaunchit$ python manage.py shell
Connected to JSHostManager [127.0.0.1:9009]
Connected to JSHost [127.0.0.1:49280]
Python 2.7.6 (default, Sep 9 2014, 15:04:36)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)

from react.render import render_component
component = render_component('/Users/avalaunchit/Projects/personal/pythonreacttest/static/components/Comment.jsx', translate=True, props={})
Traceback (most recent call last):
File "", line 1, in
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/react/render.py", line 105, in render_component
bundled_component = bundle_component(path, translate=translate)
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/react/bundle.py", line 31, in bundle_component
return webpack(path_to_config_file)
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/webpack/compiler.py", line 119, in webpack
raise six.reraise(BundlingError, BundlingError(_e.args), sys.exc_info()[2])
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/webpack/compiler.py", line 116, in webpack
bundleDir=settings.get_path_to_bundle_dir(),
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/js_host/function.py", line 35, in call
res = self.send_request(__kwargs)
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/js_host/function.py", line 92, in send_request
res_text=res.text,
BundlingError: webpack: EntryModuleNotFoundError: Entry module not found: Error: Cannot resolve module 'babel-loader' in /Users/avalaunchit/Projects/personal/pythonreacttest/static/components
at Tapable. (/Users/avalaunchit/Projects/personal/pythonreacttest/node_modules/webpack/lib/Compilation.js:350:28)
at Tapable. (/Users/avalaunchit/Projects/personal/pythonreacttest/node_modules/webpack/lib/NormalModuleFactory.js:84:21)
at /Users/avalaunchit/Projects/personal/pythonreacttest/node_modules/webpack/node_modules/async/lib/async.js:254:17
at done (/Users/avalaunchit/Projects/personal/pythonreacttest/node_modules/webpack/node_modules/async/lib/async.js:129:15)
at /Users/avalaunchit/Projects/personal/pythonreacttest/node_modules/webpack/node_modules/async/lib/async.js:32:16
at /Users/avalaunchit/Projects/personal/pythonreacttest/node_modules/webpack/node_modules/async/lib/async.js:251:21
at /Users/avalaunchit/Projects/personal/pythonreacttest/node_modules/webpack/node_modules/async/lib/async.js:575:34
at /Users/avalaunchit/Projects/personal/pythonreacttest/node_modules/webpack/node_modules/async/lib/async.js:254:17
at done (/Users/avalaunchit/Projects/personal/pythonreacttest/node_modules/webpack/node_modules/async/lib/async.js:129:15)
at /Users/avalaunchit/Projects/personal/pythonreacttest/node_modules/webpack/node_modules/async/lib/async.js:32:16
component = render_component('/Users/avalaunchit/Projects/personal/pythonreacttest/static/components/Comment.jsx', translate=True, props={})
Traceback (most recent call last):
File "", line 1, in
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/react/render.py", line 105, in render_component
bundled_component = bundle_component(path, translate=translate)
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/react/bundle.py", line 31, in bundle_component
return webpack(path_to_config_file)
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/webpack/compiler.py", line 116, in webpack
bundleDir=settings.get_path_to_bundle_dir(),
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/js_host/function.py", line 35, in call
res = self.send_request(__kwargs)
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/js_host/function.py", line 83, in send_request
raise six.reraise(FunctionTimeout, FunctionTimeout(_e.args), sys.exc_info()[2])
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/js_host/function.py", line 78, in send_request
timeout=timeout,
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/js_host/base_server.py", line 168, in send_json_request
return self.send_request(_args, *_kwargs)
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/js_host/js_host.py", line 107, in send_request
return super(JSHost, self).send_request(_args, *_kwargs)
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/js_host/base_server.py", line 159, in send_request
return func(url, *_kwargs)
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/requests/api.py", line 109, in post
return request('post', url, data=data, json=json, *_kwargs)
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/requests/api.py", line 50, in request
response = session.request(method=method, url=url, *_kwargs)
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/requests/sessions.py", line 465, in request
resp = self.send(prep, *_send_kwargs)
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/requests/sessions.py", line 573, in send
r = adapter.send(request, **kwargs)
File "/Users/avalaunchit/.virtualenvs/pythonreacttest/lib/python2.7/site-packages/requests/adapters.py", line 433, in send
raise ReadTimeout(e, request=request)
FunctionTimeout: HTTPConnectionPool(host='127.0.0.1', port=49280): Read timed out. (read timeout=10.0)

Browserify

Hi, is it possible to render Component that uses Browserify?

Bundle config files caches are cleared when a process restarts

The full path of a generated config file depends on the python process's tempfile module. Unfortunately, these generated files get new paths when the process restarts and hence a server restart will cause a new build to start, even if the node server stays up.

Might need to use a more deterministic way to generate paths, or hand it off to something in the node server.

basic_rendering example error

python example.py

Traceback (most recent call last):
  File "example.py", line 3, in <module>
    from react.render import render_component
File "/Users/hqman/project/pydev/lib/python2.7/site-packages/react/render.py", line 2, in <module>
    from optional_django import staticfiles
  File "/Users/hqman/project/pydev/lib/python2.7/site-packages/optional_django/staticfiles.py", line 2, in <module>
    from .env import DJANGO_CONFIGURED
  File "/Users/hqman/project/pydev/lib/python2.7/site-packages/optional_django/env.py", line 20, in <module>
    getattr(DJANGO_SETTINGS, 'DEBUG', None)
  File "/Users/hqman/project/pydev/lib/python2.7/site-packages/django/utils/functional.py", line 184, in inner
    self._setup()
  File "/Users/hqman/project/pydev/lib/python2.7/site-packages/django/conf/__init__.py", line 40, in _setup
    raise ImportError("Settings cannot be imported, because environment variable %s is undefined." % ENVIRONMENT_VARIABLE)
ImportError: Settings cannot be imported, because environment variable DJANGO_SETTINGS_MODULE is undefined.

No module named base_service

Hey there,
I'm getting the error No module named base_service

Error at line 4: from django_node.base_service import BaseService in django-react/django_react/services/init.py

It looks like base_service is no longer part of the django_node package.

Any ideas?

Thanks,

Use external bundle

Hello, Mark! We`ve already discussed it a bit, I want to use django-react with my own bundle, containing all required modules. So I just need to instantiate component, which is in this bundle, with props and render it. Is it possible?

List index out of range

I have a simple JSX-file, which outputs "Hello django-react", it works fine until randomly starts throwing error 500.

Environment:

Request Method: GET
Request URL: http://localhost:8000/signup

Django Version: 1.8.1
Python Version: 2.7.9
Installed Applications:
('django.contrib.contenttypes',
 'django.contrib.auth',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'react',
 'js_host',
 'webpack',
 'volu')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware')

Traceback:
File "/Users/jrasanen/.virtualenvs/reacttest/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/jrasanen/Development/volu/reacttest/volu/views.py" in signup
  29.         to_static_markup=no_js
File "/Users/jrasanen/.virtualenvs/reacttest/lib/python2.7/site-packages/react/render.py" in render_component
  106.         path = bundled_component.get_paths()[0]

Exception Type: IndexError at /signup
Exception Value: list index out of range

Console output while refreshing the page 3-10 times:

[14/May/2015 09:10:12]"GET /static/webpack/bundles/react-components/jsx__Signup-d830a531c93fdf23d1d0.js HTTP/1.1" 200 265277
[14/May/2015 09:10:29]"GET /signup HTTP/1.1" 200 3429
[14/May/2015 09:10:29]"GET /static/webpack/bundles/react-components/jsx__Signup-ac957b77ea30095bc2f6.js HTTP/1.1" 200 265298
[14/May/2015 09:10:31]"GET /signup HTTP/1.1" 200 3430
[14/May/2015 09:10:31]"GET /static/webpack/bundles/react-components/jsx__Signup-ac957b77ea30095bc2f6.js HTTP/1.1" 200 265298
[14/May/2015 09:10:38]"GET /signup HTTP/1.1" 200 3449
[14/May/2015 09:10:38]"GET /static/webpack/bundles/react-components/jsx__Signup-11528387cafe8d8fda1c.js HTTP/1.1" 200 265298
[14/May/2015 09:10:40]"GET /signup HTTP/1.1" 200 3427
[14/May/2015 09:10:40]"GET /static/webpack/bundles/react-components/jsx__Signup-11528387cafe8d8fda1c.js HTTP/1.1" 200 265298
[14/May/2015 09:10:42]"GET /signup HTTP/1.1" 200 3425
[14/May/2015 09:10:42]"GET /static/webpack/bundles/react-components/jsx__Signup-11528387cafe8d8fda1c.js HTTP/1.1" 200 265298
[14/May/2015 09:10:56]"GET /signup HTTP/1.1" 200 3503
[14/May/2015 09:10:57]"GET /static/webpack/bundles/react-components/jsx__Signup-8b546af9446e430db8fa.js HTTP/1.1" 200 265366
[14/May/2015 09:10:58]"GET /signup HTTP/1.1" 200 3481
[14/May/2015 09:10:58]"GET /static/webpack/bundles/react-components/jsx__Signup-8b546af9446e430db8fa.js HTTP/1.1" 200 265366
[14/May/2015 09:11:05]"GET /signup HTTP/1.1" 500 73901
[14/May/2015 09:11:06]"GET /signup HTTP/1.1" 500 73901
[14/May/2015 09:11:07]"GET /signup HTTP/1.1" 500 73901
[14/May/2015 09:11:18]"GET /signup HTTP/1.1" 500 73901
[14/May/2015 09:11:49]"GET /signup HTTP/1.1" 500 73901

Allow to disable caching of JSX files

I've noticed that the JSX files are somehow cached in the python process' memory, I assume for performance reasons. Changes made to a JSX file will only take effect after restarting the Django server. Could there be a way to avoid caching those JSX files? Or perhaps this feature already exists and I might have missed something in the documentation? (if so, I'm sorry!)

Thanks for a great app!

Is python-react adapted to my use-case

I am new to React (and, thus, to python-react).

I want to build a web user interface to display real-time data.

I have a python program running on the server-side that retrieves data from a data provider and does some processing on it.

What I want to do is link my program to a client-side real-time user interface to visualize it.

Questions
  1. Considering my use case, when looking at python-react am I looking at the right thing?
  2. From what I understand, python-react renders components on the server-side and then sends the rendered HTML-JS to the client. Am I correct?
    • Yes: isn't that slow? I think there is some state concept in React. Wouldn't it be faster to send state updates?
    • No: what is happening then?

django's gettext problem

how to resolve the problem gettext is not defined.

an example base template file

<html lang='zh-TW'>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="content-type" content="text/html;charset=UTF-8">
    <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1.0, width=device-width, height=device-height " />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <script type="text/javascript" src="{% url 'django.views.i18n.javascript_catalog' %}"></script>
    {% block extra_content %} {% endblock %} {% block js %} {% endblock %}
</head>
<body>
    <div id="now_lang" style="display: none">{{ LANG }}</div>
    {% csrf_token %}
    {% block content %}{% endblock %}
</body>
</html>

by add this <script type="text/javascript" src="{% url 'django.views.i18n.javascript_catalog' %}"></script>, I can call gettext in my jsx file. However, the render server will not know what gettext is.

Is there any solution for this situation ?

easier helper functions instead of webpack

After using this package for a little while, I quickly grew tired of dealing with webpack, so I wrote some helper functions to eliminate the need for it entirely.

myproject/utils.py

from django_react.render import render_component
from django.contrib.staticfiles import finders
from django.shortcuts import render

def prerender_component(jsx_path, *arg, **argv):
    preren_path = finders.find(jsx_path).replace('.jsx', '_prerenderable.jsx')
    with file(preren_path, 'w+') as prerenderable_jsx:
        prerenderable_jsx.write("import React from 'react';\n");
        with file(finders.find(jsx_path), 'r') as jsx_file:
            prerenderable_jsx.write(jsx_file.read())
        prerenderable_jsx.write("\nexport default render;");
    return render_component(preren_path, *arg, **argv)

def render_react(request, template_path, context, *arg, **argv):
    """add the prerendered html to any react components found in context"""
    # pass it a context formatted like this:
    # context = {
    #     'components': {
    #         'MyComponent': {                          # component name
    #             'jsx_path': 'test.jsx',               # relative to static root
    #             'props': {
    #                 'themessage': 'barbarblackshee',
    #             },
    #             'html': 'generated by this function'
    #         },
    #     },
    #     ...
    # }
    # then use this in the template to get the component's html
    # {{components.MyComponent.html}}
    # and this to access its props
    # {{components.MyComponent.props.themessage}}
    if 'components' in context:
        for name, component in context['components'].iteritems():
            context['components'][name]['html'] = prerender_component(component['jsx_path'], props=component['props']) if 'jsx_path' in component else 'No JSX Path Specified'

    return render(request, template_path, context, *arg, **argv)

I use render_react inside my view, in place of plain render, e.g.:
views.py

from myproject.utils import render_react

def react_test(request):
    context = {
        'components': {
            'main': {
                'jsx_path': 'test.jsx',
                'props': {
                    'themessage': 'baabaablacksheep',
                },
            },
        },
    }

    return render_react(request, 'frontend/test.html', context)

And my template:
templates/frontend/test.html

<html>
    <head>
        <title>Django + React demo</title>
    </head>
    <body>
        <br><br><br>
        <div id="tcomp">
            {{components.main.html}}
        </div>
        <script src="{{static_url}}/react/react.js" type="text/javascript"></script>
        <script src="{{static_url}}/react/JSXTransformer.js" type="text/javascript"></script>
        <script type="text/jsx" src="{{static_url}}/test.jsx"></script>
        <script type="text/jsx">
            React.render(
                <RandomMessage themessage="{{components.main.props.themessage}}"/>,
                document.getElementById('tcomp')
            );
        </script>
    </body>
</html>

static/test.jsx

var TestView = React.createClass({
    render: function() {
        return (
            <p>{this.props.message}</p>
        )
    }
});

var render = TestView;

That way the prerendered html is properly displayed, and I can mount the component using the same JSX file used to prerender it. What do you think? If I wrote a pull request implementing these as part of the package, would you consider merging it? I'm open to suggestions/criticism as well.

[bundle_dir] not being replaced by python-webpack

Not sure if this is a python-webpack issue or not but I'm filing it here since I was able to patch it locally by replacing the [bundle_dir] string in the generate_config_for_component function with a manual join of the BUNDLE_ROOT, OUTPUT_DIR and BUNDLE_DIR settings by accessing python_webpack.conf.settings directly.

Couldn't really find the area in webpack where the replacement happens and don't have time right now to dig into it deeper but it was causing python-react to write out a config file that still had the [bundle_dir] string hard coded into the config and therefore the renderer could not find the actual component because it was getting written to a directory on the root called "[bundle_dir]".

Slow component rendering

Having simple component:

var React = require('react');
var Container = React.createClass({

    render: function () {
        return (
            <div>
                Simple container
            </div>
        );
    }
});

module.exports = Container;

render_component takes about 1 second. Is there any way to improve speed of rendering? Setting django_webpack.settings.DEBUG to True doesn`t seem to help.

Use components placed outside of django app and use external webpack config

Hello, Mark! Thanks for useful app. I have two questions:

  1. JS components in my app are placed outside of django directory(and then packed with webpack to django_app/staticfiles/js/bundle.js), so it's not possible to find them using django's staticfiles finder. In addition I don`t want to make this components available via staticfiles finder. How can I configure 'django-react' to work with such layout?
  2. I have webpack.conf.js with lots of options defined. Is there any way to use this config file instead of 'django-webpack' default?

Cannot log from react

Hi,

using python-react with js-host, how can I log from react that being rendred in backend. Also using Django. Trying with console.log but nothing appears.

JS_HOST = {
'USE_MANAGER': DEBUG,
'VERBOSITY': 600
}
REACT = {
'DEVTOOL': 'eval' if DEBUG else None,
}

Stop omitting React from the bundles

Currently React is omitted from the bundles as an optimisation, but a number of folk seem to be hitting the same road block when trying to integrate it. Might be worth turning it off and adding a section to the docs about optimisation which shows how to turn it back on.

There's a downside to this, which is that the bundling process will take longer. Switching django-webpack's bundler to a persistent process with incremental compilation may alleviate that issue. See django-node+django-react's node-server branches for the underlying infrastructure to host the process.

Re #10
Re #8

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.