Giter Site home page Giter Site logo

Comments (7)

pfalcon avatar pfalcon commented on May 21, 2024

I can send correctly using bytes - resp.write(b'абвгд')

Yes, that's the correct way to do it - .write() accepts bytes object. MicroPython is more relaxed than CPython and allows to pass str in many places, but that may not work reliably for non-ASCII chars, as you noticed.

The change you made to render_template() looks plausible, but I would like to consider any other possible alternatives. Can you provide small self-contained example which reproduces the problem to speed up the resolution?

from picoweb.

tarakanov avatar tarakanov commented on May 21, 2024

Here is the script:

import picoweb

app = picoweb.WebApp(__name__)

def render_template_b(writer, template_name, args=()):
  import utemplate.source
  template_loader = utemplate.source.Loader("__main__", "templates")
  template = template_loader.load(template_name)
  for s in template(*args):
    yield from writer.awrite(s.encode('utf-8'))

@app.route("/ascii")
def index(req, resp):
    yield from picoweb.start_response(resp, content_type = "text/html")
    yield from app.render_template(resp, "ascii.tpl", ("some ascii chars",))

@app.route("/non-ascii-fix")
def test(req, resp):
    yield from picoweb.start_response(resp, content_type = "text/html; charset=utf-8")
    yield from render_template_b(resp, "non-ascii.tpl", ("абвгдe",))

@app.route("/non-ascii-error")
def test2(req, resp):
    yield from picoweb.start_response(resp, content_type = "text/html; charset=utf-8")
    yield from app.render_template(resp, "non-ascii.tpl", ("абвгдe",))

import ulogging as logging
logging.basicConfig(level=logging.INFO)
app.run(debug=True)

ascii.tpl:

{% args chars %}
<html>
ascii chars: abcde <br>
From args: {{ chars }} <br>
</html>

non-ascii.tpl:

{% args chars %}
<html>
Non ascii chars: абвгде<br>
From args: {{ chars }} <br>
</html>

from picoweb.

pfalcon avatar pfalcon commented on May 21, 2024

Ok, so my thoughts about this stuff:

  1. Ideally, I'd like .awrite() to just work with str.
  2. However, I'm a bit shy to add if isinstance(buf, str): buf = buf.encode() to it, conceptually it's "wrong" to make "well-behaving" apps, which shove the bytes in, to incur overhead of that check.
  3. Then patching it on the level of render_template(), like proposed here would be the way, right?
  4. No, wait there's p.1.
  5. Looking at StreamWriter.awrite() again, to see if it can be "optimized", in a way that bytes and str would be handled transparently. Well, it's already optimized, and that optimization depends on bytes.
  6. But well, then there's an option to introduce .awritestr(), and put conversion there. This way, both uasyncio and picoweb need to be patched now, but at least it's a scalable solution reusable for other cases.

from picoweb.

pfalcon avatar pfalcon commented on May 21, 2024

An interesting solution would be to have (a null) .encode() method on bytes, and call buf = buf.encode() unconditionally in .awrite(). That's actually how MicroPython works if built without MICROPY_PY_BUILTINS_STR_UNICODE defined. But otherwise, I saw (ugly, CPython-ridden) code which uses presence of encode/decode methods for ducktyping checks, and that's why with MICROPY_PY_BUILTINS_STR_UNICODE, there're separate method tables, even if they differ only in encode vs decode.

from picoweb.

pfalcon avatar pfalcon commented on May 21, 2024

So, overall, .awritestr() seems like the best solution.

Comments and criticism are welcome though.

from picoweb.

tarakanov avatar tarakanov commented on May 21, 2024

Right. I just want to say that I am not so experience in python yet. Now I am working on project which will use this fix. I will try to imlement it and share results.

from picoweb.

pfalcon avatar pfalcon commented on May 21, 2024

Right. I just want to say that I am not so experience in python yet.

Yes, sometimes it's not easy to decide which is the best way to fix some issue. Anyway, I went for the solution described above and implemented it in picoweb 1.6. I've also added example to test Unicode rendering functionality: https://github.com/pfalcon/picoweb/blob/master/examples/example_unicode.py .

Hopefully, this fixes issues on your side too. If not, feel free to report them.

from picoweb.

Related Issues (20)

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.