Coder Social home page Coder Social logo

webpy's Introduction

pypi python versions build status

web.py is a Python web framework that is as simple as it is powerful.

Visit http://webpy.org for more information.

To install web.py, please run:

python3 -m pip install web.py

webpy's People

Contributors

aaronsw avatar aisk avatar akash0x53 avatar anandology avatar asldevi avatar blueyed avatar bnoordhuis avatar btbytes avatar cclauss avatar cellularmitosis avatar fredludlow avatar iredmail avatar jimgregory avatar jzellman avatar kkroo avatar liuming-dev avatar nopri avatar patryk avatar pjz avatar pricechild avatar pslacerda avatar pysquared avatar rafalstapinski avatar sandesh247 avatar schneidersoft avatar scottbarnes avatar serverhorror avatar shell909090 avatar varunpurohit76 avatar zashas 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  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

webpy's Issues

pgdb doesn't work with db.py.

I only have pgdb installed on my system and I can't use Postgrès with web.db.
I get the following exceptions:

File "/usr/lib64/python2.6/site-packages/web/db.py", line 918, in _connect
conn.set_client_encoding('UTF8')
AttributeError: 'pgdbCnx' object has no attribute 'set_client_encoding'

Indeed, pgdb module doesn't provide this method or any equivalent.

Here's a patch for the db.py file that works at home, I think it will preserve the behavior for psycopg* users. I did'nt figure out how to know which module in the was used in the _connect contexte, so I exploited the AttributeError exception to call the correct method.

918c918,921
<         conn.set_client_encoding('UTF8')

---
>         try:
>             conn.set_client_encoding('UTF8')
>         except (AttributeError):
>             conn.cursor().execute("set client_encoding to 'UTF-8'")

There's the same issue with _connect_with_pooling, but I didn't meet her ;)
Have a nice day :)

Multi duplicate session Set-Cookie header after 9e927c4 New ThreadedDict

After commit 9e927c4, I found web.session will app.add_processor(self._processor) on each request, cause session set-cookie multi times.
Here's the playback:

example from http://webpy.org/cookbook/sessions

import web
web.config.debug = False
urls = (
    "/count", "count",
    "/reset", "reset"
)
app = web.application(urls, locals())
session = web.session.Session(app, web.session.DiskStore('sessions'), initializer={'count': 0})

class count:
    def GET(self):
        session.count += 1
        return str(session.count)

class reset:
    def GET(self):
        session.kill()
        return ""

if __name__ == "__main__":
    app.run()

Use newest webpy git source

cat@cat-mbp ~/i(master) $ ./app.py 
init session here
http://0.0.0.0:8080/

cat@cat-mbp ~/i(master) $ curl -I http://localhost:8080/count
HTTP/1.1 200 OK
Set-Cookie: webpy_session_id=7e550992eff539cb17ce03484f25f38be9ef525b; Path=/; httponly
Connection: close
Date: Thu, 24 Feb 2011 10:14:40 GMT
Server: CherryPy/3.1.2 WSGI Server

cat@cat-mbp ~/i(master) $ curl -I http://localhost:8080/count
HTTP/1.1 200 OK
Set-Cookie: webpy_session_id=b8fd314485ae4012eae8bb098a1b9efebd5f6a68; Path=/; httponly
Set-Cookie: webpy_session_id=b8fd314485ae4012eae8bb098a1b9efebd5f6a68; Path=/; httponly
Connection: close
Date: Thu, 24 Feb 2011 10:14:40 GMT
Server: CherryPy/3.1.2 WSGI Server

cat@cat-mbp ~/i(master) $ curl -I http://localhost:8080/count
HTTP/1.1 200 OK
Set-Cookie: webpy_session_id=59f233edc5da2037e88e7a7292e6069a84a591d7; Path=/; httponly
Set-Cookie: webpy_session_id=59f233edc5da2037e88e7a7292e6069a84a591d7; Path=/; httponly
Set-Cookie: webpy_session_id=59f233edc5da2037e88e7a7292e6069a84a591d7; Path=/; httponly
Connection: close
Date: Thu, 24 Feb 2011 10:14:41 GMT
Server: CherryPy/3.1.2 WSGI Server

Use 0.34 release version https://github.com/webpy/webpy/zipball/webpy-0.34

cat@cat-mbp ~/i(master) $ ./app.py 
init session here
http://0.0.0.0:8080/

cat@cat-mbp ~/i(master) $ curl -I http://localhost:8080/count
HTTP/1.1 200 OK
Set-Cookie: webpy_session_id=02da716a33a5c183a02935cd816965a92f9766a3; Path=/
Connection: close
Date: Thu, 24 Feb 2011 10:23:20 GMT
Server: CherryPy/3.1.2 WSGI Server

cat@cat-mbp ~/i(master) $ curl -I http://localhost:8080/count
HTTP/1.1 200 OK
Set-Cookie: webpy_session_id=281774011de60cb488f299488dea974f88bf9b04; Path=/
Connection: close
Date: Thu, 24 Feb 2011 10:23:21 GMT
Server: CherryPy/3.1.2 WSGI Server

cat@cat-mbp ~/i(master) $ curl -I http://localhost:8080/count
HTTP/1.1 200 OK
Set-Cookie: webpy_session_id=f109babbf69c6fe811fb9561ba0eeb69c9216da7; Path=/
Connection: close
Date: Thu, 24 Feb 2011 10:23:21 GMT
Server: CherryPy/3.1.2 WSGI Server

support ORDER BY in db.update

Bug reported in Launchpad.

https://bugs.launchpad.net/webpy/+bug/598080

Although UPDATE ... SET ... ORDER BY .... is valid SQL, current db module doesn't support this. Current documentation shows arguments for db.select works for db.update, and there's no mention about order is not working in update.

Supposed to be work:

ret = self.db.update('Articles', vars = val, 
    where = 'bSerial = $board_id AND aIndex >= $index', 
    order = 'aIndex DESC', 
    aIndex = web.SQLLiteral('aIndex + 1'))

Result:

ERR: UPDATE Articles SET order = 'aIndex DESC', aIndex = aIndex + 1 
    WHERE bSerial = 1371L AND aIndex >= 48L

Finally:

ProgrammingError: (1064, "You have an error in your SQL syntax; 
    check the manual that corresponds to your MySQL server version for 
    the right syntax to use near 'order = 'aIndex DESC', aIndex = aIndex + 1 
    WHERE bSerial = 1371 AND aIndex >= 48' at line 1")

Implement a better reloader

The current reloader tries to reload modules, it doesn't work well if there is some global state. Things like sessions etc. are not working with the reloader.

We need a new reloader that restarts the whole process when it detects file changes.

All documentation links are broken

Every time I search for WebPY documentation on google, I am linked to the correct page, but with a trailing slash. The docs only work without a trailing slash. Maybe add an optional trailing slash to the urls?

render_genshi ignores type='html'

web/contrib/template.py has this logic:

    if self._type == "text":
        ...
    else:
        cls = None
        type = None ##

    ...
        if type:
            return stream.render(type)

On the line where I put the ##, it should say type=self._type. Currently, calling render_genshi(type='html') and render_genshi(type='xhtml') do the exact same thing, which seems like a mistake. (For the record, the current code is always picking xhtml.)

have memoize recalculate in background before it's needed

Right now using memoize with background=True, if you ask for a result that's expired, it'll recalculate it in a new thread but send you the old result. It'd be nice if there was an option to have an ongoing thread that would recalculate the answer just before it expired.

4XX Handlers inconsistent

The NotFound and InternalError handlers are special... which is confusing when you want to use some of the other error handlers (like Forbidden or Unauthorized) in the same way.

I propose making them all a little more uniform. Here's an untested patch to illustrate my intent:
http://pastebin.com/TgB6LH5q

Rendering multiple select dropdowns with a list of values

When (re) rendering Dropdowns with multiple selects, one can only pass a single value:

fdSelect = form.Form(
     form.Dropdown('Fire',
         ['q', 'b', 'c'],
         form.notnull,
         **{'multiple': None, 'size': 2}
         ),
 )

fd.Fire.value = 'b'
fd.render() works as expected:
...\n  b\n  c\n....
fd.Fire.value = ['a', 'b', 'c']
fd.render() does not select anything
...\n  b\n  c\n....

This patch seems to fix that behaviour:

--- form.py.orig    2011-01-28 11:24:58.080150680 -0600
+++ form.py 2011-01-28 11:28:59.346763259 -0600
@@ -240,8 +240,10 @@
             else:
                 value, desc = arg, arg 
 
-            if self.value == value: select_p = ' selected="selected"'
-            else: select_p = ''
+            if (self.value is not None and value in self.value):
+                select_p = ' selected="selected"'
+            else:   
+                select_p = ''
             x += '  %s\n' % (select_p, net.websafe(value), net.websafe(desc))
             
         x += '\n'

form.Form.valididates(), fill() and _validate don't affect the "checked" status of Checkbox elements

Cf: http://groups.google.com/group/webpy/browse_thread/thread/ea49983d0d839fa6?pli=1

from web import form
from web.utils import storify

f = form.Form(
        form.Checkbox('contact_me', checked=True,
description='spam_me')
)

f.fill(kw=dict()) # no adding.
assert '''checked="checked"''' in f.render()

f = form.Form(
        form.Checkbox('contact_me', checked=False,
description='spam_me')
)
f.fill(kw=dict()) # no adding.
assert '''checked="checked"''' not in f.render()

f.fill(kw=dict(contact_me=True)) # add it.
assert '''checked="checked"''' in f.render(), "didn't fill in"

'fill' is just a shorthand to 'valididates()', which doesn't know how
to
do much except set the 'value' attribute.

I observe in my tests that indeed, submitted forms don't "stay"
checked. Validators just seem to look at the 'value' attribute, and
that is it. (cf. the _validate method).

The hackish solution is to wire in that "checked means value is valid"
thing yourself. Ugly though!

Form doesn't render correctly when Input's pre or post arguments are set to unicode

Try to run this code:

# coding: utf-8

import web
from web import form

urls = (
    '/(.*)', 'hello'
)
app = web.application(urls, globals())

testForm1 = form.Form(form.Textbox("test", description=u"Тест", pre='Еще')) # works
testForm2 = form.Form(form.Textbox("test", description=u"Тест", pre=u'Еще')) # raises error

class hello:        
    def GET(self, name):
        return testForm2.render()

if __name__ == "__main__":
    app.run()

datestr() cannot process DATETIME field in Sqlite3 properly

I've test the basic blog code example with a Sqlite3 database. But everytime it collapse when processing $datestr(post.posted_on).

I then read the webpy code, and it seems that the datestr() function cannot process Sqlite3's DATETIME field, Python's type() function regards it as a 'str'(or 'Unicode') type...

regex is not working in top level app

When using subapplications regexes, the top level url definitions behave differently then regexes in subapplications. This is an example based on code in http://webpy.org/cookbook/subapp.

blog.py:

import web

urls = (
  "", "reblog",
  "/(blog|Blog)", "blog"  #change from original
)

class reblog:
    def GET(self): raise web.seeother('/')

class blog:
    def GET(self, path):
        return "blog " + path

app_blog = web.application(urls, locals())

code.py

import web
import blog
urls = (
  "/(blog|Blog)", blog.app_blog,  #change from original
   #  "/blog", blog.app_blog,
  "/(.*)", "index"
)

class index:
    def GET(self, path):
        return "hello " + path

app = web.application(urls, locals())

if __name__ == "__main__":
    app.run()

The regex /(blog|Blog) is the same in blog.py and code.py however request GET http://localhost:1111/blog/Blog does not return the expected result. If the regex is commented out in code.py and replaced with the line below it GET request returns an expected result.

Submit buttons lost value attribute

Between .32 and .33, submit buttons no longer have text. We use the description variable, but its cleared out on instantiation. I have attached a patch to fix carry the value attribute to the tag rendering,

diff --git a/web/form.py b/web/form.py
index 750fe6f..8cb7a1c 100644
--- a/web/form.py
+++ b/web/form.py
@@ -312,7 +312,8 @@ class Button(Input):
def render(self):
attrs = self.attrs.copy()
attrs['name'] = self.name

  •    return '<button %s>%s</button>' % (attrs, self.description)
    
  •    attrs['value'] = self.value
    
  •    return '<button %s>%s</button>' % (attrs, self.value)
    

    class Hidden(Input):
    """Hidden Input.

Session Cookies paths are wrong

Session cookies are assuming that the app runs on a domain's or subdomain's root.
The cookie path should be set according to

os.environ['REAL_SCRIPT_NAME']

Validation of forms with value attribute set to an int

If the value attribute of a dropdown or radio button element is set to an integer and validation of the form containing that element fails the element's state is lost in the redisplayed form.

If the following form was submitted with the textbox left blank and the first radio button selected the form displayed after validation would show an empty textbox and no radio button selected.
simple_form = form.Form(
form.Textbox('test',
form.notnull,
),
form.Radio('example',
[1,2,3,4],
)
)

I think this happens because the form post is u/str and thus the value checks fail. Maybe this could be fixed by converting the values to strings for the test of equality in the render functions for these elements.

243c243
<             if self.value == value: select_p = ' selected="selected"'

---
>             if self.value == str(value): select_p = ' selected="selected"'
266c266
<             if self.value == arg:

---
>             if self.value == str(arg):

When there are multiple <input type="file" name="fname"> with the same name, web.input(fname={}) returns only the last one.

Reported on Launchpad by Hudson Lee on 2010-04-11.

https://bugs.launchpad.net/webpy/+bug/560278

 

In webpy .34 release.

When there are multiple <input type="file" name="fname"> with the same name, web.input(fname={}) returns only the last one.

This happens to be how: <input type="file" multiple=""> submits it's files.
(works in ff3.6 & recentish chrome/safari)

My fix for this is in utils.py storify() line 147: change

else:
    value = value[-1]

TO:

elif not isinstance(defaults.get(key), dict):
    value = value[-1]

Related Suggested Change:

I hate having todo: web.input(email=[], phone=[], userfile={}) to get lists when I have multiple form elements with the same name.

Why not be able to do something like this: web.input(_nolists=False) [I can't think of a good name] then in webapi.py input() line 278: add 1 line…

defaults.setdefault('_nolists', True)

and in utils.py storify() add:
  
_nolists = defaults.pop('_nolists')

… and ...

elif _nolists and not isinstance(defaults.get(key), dict):
    value = value[-1]

That forces returning FieldStorage objects (instead of their .value) when you do web.input(_nolists=False). I think thats ok for a long list of files. People usually need the file name in any case.

A cleaner way to add this might be an input() wrapper something like web.inputs() which always returns lists for fields with the same name.

Let me know what you think about something like that.

-hudlee [[email protected]]

Cookie and raise redirect

session.request_token = '123'
raise web.redirect('http://example.com/oauth')

This code must set session cookie with redirect response. But it doesn't do.

DB insert with no values doesn't work with mysql

DB insert with no values doesn't work with mysql, even though it works with sqlite.

>>> db.insert("mytable")
ERR: INSERT INTO mytable DEFAULT VALUES

The correct syntax for MySQL is:

INSERT INTO mytable () VALUES();

(Originally reported by Ole Trenner in the mailing list.)

web.debugerror doesn't display utf-8

Cannot get error display correctly, check this test case

# coding: utf-8
import web
urls = (
    '/(.*)', 'hello'
)
app = web.application(urls, globals())
class hello:        
    def GET(self, name):
        a = u"ошибка" # if remove this line and coding declaration—then everything is fine
        raise Exception("test")
if __name__ == "__main__":
    app.run()

Most of the time i get this in the browser instead of pretty djangoerror:

Traceback (most recent call last):
  File "/Library/Python/2.6/site-packages/web/wsgiserver/__init__.py", line 1174, in communicate
    req.respond()
  File "/Library/Python/2.6/site-packages/web/wsgiserver/__init__.py", line 544, in respond
    self._respond()
  File "/Library/Python/2.6/site-packages/web/wsgiserver/__init__.py", line 558, in _respond
    for chunk in response:
  File "/Library/Python/2.6/site-packages/web/utils.py", line 353, in safestr
    return str(obj)
  File "/Library/Python/2.6/site-packages/web/template.py", line 1260, in __str__
    return self["__body__"].encode('utf-8')
  File "/Library/Python/2.6/site-packages/web/template.py", line 1253, in __getitem__
    self["__body__"] = u"".join(self._data)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 19: ordinal not in range(128)

reloader + lighttpd + external modules

The reloader does not appear to reload external modules under lighttpd. The reloader works as expected under the dev server although you must ensure that the modules are imported as "import x" and not as "from y import x".

Add dynamic forms

A dynamic form class (that allows adding elements dynamically) would be nice:

class DynamicForm(web.form.Form):
    def add_input(self, new_input):
        list_inputs = list(self.inputs)
        list_inputs.append(new_input)
        self.inputs = tuple(list_inputs)

It can be used like this:

form = DynamicForm()
for k,v in some.items():
    form.add_input(web.form.Checkbox(v, value=k))

When there are multiple <input type="file"> with the same name, web.input() only returns the last one.

In webpy .34 release.

When there are multiple <input type="file" name="fname"> with the same name, web.input(fname={}) only returns the last one.

This is also how:
<input type="file" multiple=""> submits it's files. (works in ff3.6 & recentish chrome/safari)

My fix for this is in utils.py storify() line 147: change
else:
value = value[-1]
TO:
elif not isinstance(defaults.get(key), dict):
value = value[-1]

Related Suggested Change:
I hate having todo: web.input(email=[], phone=[], userfile={}) to get lists when I have multiple form elements with the same name.

Why not be able to do something like this: web.input(_nolists=False) [I can't think of a good name] then in webapi.py input() line 278: add 1 line…
defaults.setdefault('_nolists', True)

and in utils.py storify() add:
_nolists = defaults.pop('_nolists')
… and ...
elif _nolists and not isinstance(defaults.get(key), dict):
value = value[-1]

That forces returning FieldStorage objects (instead of their .value) when you do web.input(_nolists=False). I think thats ok since everyone probably wants that with a long list of files.

Let me know what you think about something like that.

-hudlee [[email protected]]

Invalid GAE templates generated

Problem is in change
http://github.com/webpy/webpy/commit/84205cf4a0495ec5a10cb2d6d9904262d9e7ad68

This change results in such a template:

from web.template import CompiledTemplate, ForLoop, TemplateResult

import snippets
# encoding: utf-8 
    join_ = main._join; escape_ = main._escape
def main (username):
    __lineoffset__ = -4
    loop = ForLoop()
    self = TemplateResult(); extend_ = self.extend
    extend_([u'\n'])
    extend_([u'<tr>\n'])
    extend_([u'        <td/><td colspan="2">Hello, ', escape_(username, False), u'!</td><td/>\n'])
    extend_([u'</tr>\n'])

    return self

main = CompiledTemplate(main, './templates/main.html')

# encoding: utf-8 
    join_ = time_reports_individual._join; escape_ = time_reports_individual._escape
def time_reports_individual (periods):
...

And exception:

join_ = main._join; escape_ = main._escape
^
    IndentationError: unexpected indent

Instead this should look as this IMHO:

        code = code.replace("__template__", name, 1)

        out.write(code)

        out.write('\n\n')
        out.write('%s = CompiledTemplate(%s, %s)\n\n' % (name, name, repr(path)))
        # inject "join_ = ..; escape_ = .." into the code.. 
        # That is required to make escape functionality work correctly. 
        out.write('\njoin_ = %s._join; escape_ = %s._escape\n' % (name, name))

radio bug in form.py

In form.py
I find a bug:

 262           attrs['value'] = arg  #arg -> value
 263           if self.value == arg:  #arg -> value
 264               attrs['checked'] = 'checked'

"$continue" vs. "$ continue" in templates

0.34 appears to be sensitive to whitespace before continue or break statements in templates. When I leave out the whitespace (which is the style used in the Templating section of the tutorial):

$def with (requests, errmsg)
$var title: Test
$ contacts = ['Craig', '', 'Jay']
$for (i, contact) in enumerate(contacts):
    $if contact == '':
        $continue
    Contact $i: $contact 

I get this error:

TypeError: emit() takes exactly 2 arguments (3 given)

The error goes away if there is a blank between the '$' and the continue.

Error when my POST method just redirects

I had an unexpected behavior while I had a form page and my controller had POST method, but it just redirected to another page.
It looked something like:
class foo:
def POST(self):
raise web.seeother('/bar')

and when I wrote something like:
class foo:
def POST(self):
form = web.input(somefield={})
raise web.seeother('/bar')
it worked!

Too strange. Please, take a look at it.

Automatic form rendering creates tables

Automatic forms should create a more CSS friendly and contemporary HTML. For example <li>-Elements with <label>s and <input>-Elements.

Another interesting feature could be automatic ids generated from the input's name, like

<li id="prefix-username">
    <label for="username_generated_element">Name of the User</label>
    <input id="username_generated_element" type="text" name="username">
</li>

With an optional prefix this could greatly ease CSS styling.

pypy __setitem__ error

  Traceback (most recent call last):
    File "/Users/bonkabonka/pypy-1.3/site-packages/web/wsgiserver/__init__.py", line 1174, in communicate
      req.respond()
    File "/Users/bonkabonka/pypy-1.3/site-packages/web/wsgiserver/__init__.py", line 544, in respond
      self._respond()
    File "/Users/bonkabonka/pypy-1.3/site-packages/web/wsgiserver/__init__.py", line 556, in _respond
      response = self.wsgi_app(self.environ, self.start_response)
    File "/Users/bonkabonka/pypy-1.3/site-packages/web/httpserver.py", line 201, in __call__
      return self.app(environ, xstart_response)
    File "/Users/bonkabonka/pypy-1.3/site-packages/web/application.py", line 273, in wsgi
      self.load(env)
    File "/Users/bonkabonka/pypy-1.3/site-packages/web/application.py", line 372, in load
      ctx[k] = safeunicode(v)
  AttributeError: ThreadedDict instance has no attribute '__setitem__'

DB.delete does not work with the using clause

When the db module constructs a delete query with the USING keyword, the USING clause is appended after the WHERE clause. Not sure if this valid for other flavors of SQL, but it is against MySQL syntax.

For instance the following code:

web_app.bootleg.bootlegdb.delete('feature_mapping',
        using='feature_mapping,attributes',
        where='feature_mapping.attribute_id=attributes.attribute_id AND '
              'feature_mapping.feature=$feature AND '
              'attributes.attribute_name IN $attributes',
        vars={'feature': feature,
              'attributes': attributes})

Will generate the following query:

DELETE FROM feature_mapping WHERE feature_mapping.attribute_id=attributes.attribute_id AND feature_mapping.feature='fozzie_spam' AND attributes.attribute_name IN ('FB_SUSPECT_1_06') USING feature_mapping,attributes

This results in a syntax error. Simply putting the USING clause before the WHERE clause solves the issue.

wsgi.errors: str object has no attribute write

Today I'm update my Debian server and got the error:

Traceback (most recent call last):
  File "/usr/lib/pymodules/python2.6/web/wsgiserver/__init__.py", line 1174, in communicate
    req.respond()
  File "/usr/lib/pymodules/python2.6/web/wsgiserver/__init__.py", line 544, in respond
    self._respond()
  File "/usr/lib/pymodules/python2.6/web/wsgiserver/__init__.py", line 556, in _respond
    response = self.wsgi_app(self.environ, self.start_response)
  File "/usr/lib/pymodules/python2.6/web/httpserver.py", line 237, in __call__
    return self.app(environ, xstart_response)
  File "/usr/lib/pymodules/python2.6/web/httpserver.py", line 212, in __call__
    return self.app(environ, start_response)
  File "/usr/lib/pymodules/python2.6/web/httpserver.py", line 237, in __call__
    return self.app(environ, xstart_response)
  File "/usr/lib/pymodules/python2.6/web/application.py", line 293, in wsgi
    start_resp(status, headers)
  File "/usr/lib/pymodules/python2.6/web/httpserver.py", line 233, in xstart_response
    out = start_response(status, response_headers, *args)
  File "/usr/lib/pymodules/python2.6/web/httpserver.py", line 234, in xstart_response
    self.log(status, environ)
  File "/usr/lib/pymodules/python2.6/web/httpserver.py", line 251, in log
    print >> outfile, utils.safestr(msg)
AttributeError: 'str' object has no attribute 'write'

It's just when I run application.
When I'm use request emulation, it's okay.

Support UTF-8 encoding in templates

This raises UnicodeDecodeError:
test.py:

import web, os 
render = web.template.render(os.path.abspath(os.path.dirname(__file__))) 
render.test() 

test.html:

$var array = [u"один", u"два", u"три"] 
$ test = u"один" 
<p>just a test</p>

To fix it I had to change line 1011 in _load_template in template.py to this:

return Template(open(path).read().decode("utf-8"), filename=path, **self._keywords)

Form class is not new-style class

Form class is not new-style class. I was trying to call super(MyForm, self).__init__(*inputs) in my custom form class but no success since super() only works for new-style classes.

Form class should be defined as follow

class Form(object): instead of class Form:

Add ability to set web-server port via API

Hi,

I am using web.py as an embedded webserver in my app. Because there is no way to set the port served programatically I have to do this

    import sys; sys.argv[1] = '8080'    #Yuck
    self.app = web.application(xxxx)
    thread.start_new_thread(self.app.run, ())

Otherwise webpy assumes the first command line argument it its port (which it is not as my app has many other command line args)

sendmail needs to be refactored

The send logic should be pulled out so it can be applied to a message from anywhere. And if _EmailMessage is going to have all those features they ought to be public. (Or was it just copied from the Email module?)

%s in queries don't work

>>> import web; db = web.database(dbn='postgres', db='template1')
>>> db.select('dual', where="foo like 'foo%'")
ERR: SELECT * FROM calls WHERE foo like 'foo%'
Traceback (most recent call last):
   ...
IndexError: list index out of range

This should work, but doesn't since it tries to interpolate the string. Instead I use this workaround:

db.select('calls', where="foo like 'foo%%'")

but web.py should do that automatically, since that's totally unintuitive.

WARNING: Fixing this will probably break the workaround, which means it's a backwards-incompatible change. On the other hand, I think SQL treats % the same as %% in most cases, so it's probably not a huge deal.

Radio buttons with different value and description

The following webpy form:
simple_form = form.Form(
form.Radio('sex',
[('xy', 'male'),('xx', 'female')],
description='Select your sex',
),
)

Generates:
male
female

Not the expected:
male
female

I think this patch will fix the problem:
--- form.py 2010-03-20 13:40:07.000000000 -0400
+++ form_update.py 2010-05-10 13:05:30.000000000 -0400
@@ -262,8 +262,8 @@
attrs = self.attrs.copy()
attrs['name'] = self.name
attrs['type'] = 'radio'
- attrs['value'] = arg
- if self.value == arg:
+ attrs['value'] = value
+ if self.value == value:
attrs['checked'] = 'checked'
x += '<input %s/> %s' % (attrs, net.websafe(desc))
x += ''

From: http://groups.google.com/group/webpy/browse_thread/thread/b1de272a051b8d41

Problem setting Content-type header in web.sendemail

Cannot email html message.

If I set "Content-Type: text/html" header it simply appends it to default "text/plain", resulting two "Content-type" headers in the same message.
eg
Content-Type: text/plain; charset="utf-8"
Content-Type: text/html; charset=UTF-8

And message is treated as text/plain, but i need it to be html.

Sending email with "Content-type: multipart/alternative" (with text and html messages) is also impossible, since when I include html message as attachment, it automatically sets "Content-type: multipart/mixed" and my html message becomes attachment.

DropDown control don't work's fine with table records in Google App Engine Environment

I used this example code to reproduce the error:

# in the forms.py 
result = data.all_categories() # this method return all records of table category in GAE/big table format. 
args = [(row.key().id(), row.title) for row in result] 
new_post = form.Form( 
    form.Dropdown('category', args), 
    form.Textbox('title'), 
    form.Textarea('text'), 
    form.Dropdown('language', [('pt', 'Portuguese'), ('en', 
'English')]), 
    form.Button('Submit!') 

# in code.py 
class Post: 
    def GET(self): 
        frm = forms.new_post() 
        return render.full(render.form(frm)) 
    def POST(self): 
        global last_updated 
        frm = forms.new_post() 
        if frm.validates(): # in this point the error.
            data.save_entry(frm.d) 
            last_updated = data.last_updated() 
            raise web.seeother('/') 
        else: 
            return render.full(render.form(frm)) 

IMHO the root cause of the problem is the 'big table' format, I say this because the form generated by the GET method is correct(It has the Category A, Category B) but when I submit the form and the forms.validates() is called the error occurs.

The problem is in the forms.py in this function:

def attrget(obj, attr, value=None): 
    if hasattr(obj, 'has_key') and obj.has_key(attr): return obj[attr] 
    if hasattr(obj, attr): return getattr(obj, attr) 
    return value 

generate this error:

<type 'exceptions.AttributeError'>: 'unicode' object has no attribute 
'has_key' 
      args = ("'unicode' object has no attribute 'has_key'",) 
      message = "'unicode' object has no attribute 'has_key'"

Multiple queries using db.query() raises a ProgrammingError

Reported on Launchpad by by Brian J Ewing on 2010-11-08.

https://bugs.launchpad.net/webpy/+bug/672538

 

db.query("INSERT INTO table1 (field1, field2) VALUES ('value', 'value');" +
    " UPDATE table2 SET foo='bar'")

This works fine, however a _mysql_exceptions.ProgrammingError is raised:

_mysql_exceptions.ProgrammingError: (2014, 
    "Commands out of sync; you can't run this command now") 
in <bound method Cursor.__del__ of <MySQLdb.cursors.Cursor object at 0x>>

db.query tries to return the result from the last query without first freeing the result of the first, and MySQLdb raises this exception

Optimize multiple_insert

multiple_insert is supposed to be a faster way to add things to the database, but it does a lot of string concatenation and object creation and concatenation, which is very slow. It should be optimized to reduce these.

Quote column names when generating SQL

Bug reported on Launchpad by Martin Janda on 2010-06-30.

https://bugs.launchpad.net/webpy/+bug/600164

 

web.db for postgresql writes the column names in SQL as:

INSERT INTO log_changes (action, user, time) VALUES ...

But what if the column name is from the keyword as a column 'user' in the example?

Solution is to add double quotes around column name. For example:

INSERT INTO log_changes ("action", "user", "time") VALUES ...

Yes, I know, now it can be solved by using web.db.query method.

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.