I will dive straight into the code of the application I'm developing using Google App Engine in Python:
import os
import webapp2
import jinja2
from google.appengine.ext import db
template_dir = os.path.join(os.path.dirname(__file__), 'templates')
jinja_env = jinja2.Environment(loader = jinja2.FileSystemLoader(template_dir), autoescape=True)
class Handler(webapp2.RequestHandler):
def write(self, *a, **kw):
self.response.out.write(*a, **kw)
def render_str(self, template, **params):
t = jinja_env.get_template(template)
return t.render(params)
def render(self, template, **kw):
self.write(self.render_str(template, **kw))
class Users(db.Model):
name = db.StringProperty(required = True)
password = db.StringProperty(required = True)
email = db.EmailProperty(required = True)
address = db.PostalAddressProperty(required = True)
join_date = db.DateTimeProperty(auto_now_add = True)
dob = db.DateTimeProperty()
phone = db.PhoneNumberProperty()
class Orders(db.Model):
name = db.StringProperty(required = True)
email = db.EmailProperty(required = True)
address = db.PostalAddressProperty(required = True)
class MainPage(Handler):
def get(self):
self.render("home.html")
class Register(Handler):
def get(self):
self.render("signup-form.html")
def post(self):
name = self.request.get("username")
password = self.request.get("password")
verify = self.request.get("verify")
email = self.request.get("email")
address = self.request.get("address")
phone = self.request.get("phone")
a = Users(name = name, password = password, email = email, address = address, phone = phone)
a.put()
self.response.write("Registration successful!")
class MP(Handler):
def get(self):
self.render("mp.html")
def post(self):
self.render("order2.html")
class Order2Login(Handler, Register):
def get(self):
self.render("orderlogin.html")
def post(self):
old_usr = self.request.get("loginname")
old_pwd = self.request.get("loginpwd")
ans = a.filter("name =", old_usr).filter("password =", old_pwd)
if ans:
self.response.write("You are a registered member!")
else:
self.response.write("You are NOT registered.")
class Order2New(Handler):
def get(self):
self.response.write("New user yeah")
app = webapp2.WSGIApplication([('/', MainPage),
('/register', Register),
('/mp', MP),
('/order2new', Order2New),
('/order2login', Order2Login)], debug=True)
Now, in the Order2Login class, I needed to access the database object 'a' so that I can confirm whether a user is already a member of my website. Now, for that, I inherited the Register class in my Order2Login class, since the 'a' object was initially created in the Register class.
However, after running my application on my local machine, I get the following error:
TypeError: Error when calling the metaclass bases
Cannot create a consistent method resolution
order (MRO) for bases Handler, Register
What seems to be the problem in my code?
Inheriting like that doesn't make any sense at all. Even apart from the metaclass problem, inheriting wouldn't make that variable available anyway, since it's a local variable. And in any case, these are two completely separate requests, so data does not persist between them.
But I have no idea why you think you need access to that variable in any case. The User object was persisted to the datastore: in the login view, you don't want to query a, which is a single instance and doesn't have a filter method anyway, you want to query the User class.
Related
I'm using factory_boy to generate arbitrary data to run tests. but after each test it doesn't delete files automatically. Is there anything I should add?
Any suggestion is highly appreciated
Model for test
class TrackFactory(factory.django.DjangoModelFactory):
class Meta:
model = "tracks.Track"
id = factory.Faker("uuid4")
filename = "Track 01 - track"
created_by = factory.SubFactory(UserFactory)
file = factory.django.FileField(filename="test.mp3")
track_length = 145
#classmethod
def _create(cls, model_class, *args, **kwargs):
instance = cls.build(*args, **kwargs)
instance.save()
return instance
Test
class TestViewDeleteTrack(AuthorizedApiTestCase):
def setUp(self):
self.url = reverse(list-track)
self.user_data = UserFactory()
self.data = TrackFactory(created_by=self.user_data)
self.client.force_authenticate(user=self.user_data)
def test_list_tracks(self):
self.get_and_assert_equal_status_code(status.HTTP_200_OK)
def test_delete_track_valid_pk(self):
self.delete_and_assert_equal_status_code(
"delete-track",
self.data.pk,
status.HTTP_204_NO_CONTENT,
)
custom methods for testing used above
def get_and_assert_equal_status_code(self, status_code):
response = self.client.get(self.url)
self.assertEqual(response.status_code, status_code)
return response
def delete_and_assert_equal_status_code(self, url_name, pk, status_code):
url = reverse(url_name, kwargs={"pk": pk})
response = self.client.delete(url)
self.assertEqual(response.status_code, status_code)
Files arent deleted, just the database field that points to the file, you can remove them in your teardown method.
import shutil
class MyTest(AuthorizedApiTestCase):
...
def tearDown(self):
# modify to actually delete what you want to delete.
shutil.rmtree(settings.UPLOAD_FOLDER)
there is also a tearDownClass which is the reverse of the setUpClass
I'm trying to get a todo_ID using GET method. I'm still new at using sqlalchemy and most of the things i have tried are telling me that sqlalchemy doesn't use them. Also, can someone tell me how to use HEAD, i want my methods to return http statuses, i kinda tried using them and imported the render template but when i try to use them it says it has no idea what they are.
this is my attempt at looking at a tutorial and making changes
from flask import Flask, jsonify,json, request, render_template, abort
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config.from_pyfile('Config.py')
db = SQLAlchemy(app)
class JsonModel(object): # Class for making objects JSON serializable
def as_dict(self):
return {c.name: getattr(self, c.name) for c in self.__table__.columns}
class User(db.Model, JsonModel): # Class which is a model for the User table in the database
User_ID = db.Column(db.Integer, primary_key = True)
FirstName = db.Column(db.String(20))
LastName = db.Column(db.String(20))
def __init__(self,User_ID,FirstName, LastName):
self.User_ID = User_ID
self.FirstName = FirstName
self.LastName = LastName
class Todo(db.Model, JsonModel): # Class which is a model for the Todo table in the database
todo_ID = db.Column(db.Integer, primary_key = True)
UserID = db.Column(db.Integer, db.ForeignKey("user.User_ID"))
details = db.Column(db.String(30))
def __init__(self, UserID, details):
self.UserID = UserID
self.details = details
#app.route('/todo', methods = ['GET']) # Uses GET method to return all information in the database.
def index():
return json.dumps([u.as_dict() for u in User.query.all()+Todo.query.all()]), 201
#app.route('/todo/<int:todo_ID>', methods = ['GET'])
def get(todo_ID):
query = Todo.query.get()
return {'todo': [dict(zip(tuple(query.keys()), i)) for i in query.cursor if i[1] == todo_ID]}
#app.before_first_request #Creates everything before the first request.
def startup():
db.create_all()
if __name__ == '__main__':
app.run()
My most recent attempt was:
#app.route('/todo/<int:todo_ID>', methods = ['GET'])
def get(todo_ID):
query = Todo.query("select * from Todo")
return {'todo': [dict(zip(tuple(query.keys()), i)) for i in query.cursor if i[1] == todo_ID]}
And the error that I get is this.
query = Todo.query("select * from Todo")
TypeError: 'BaseQuery' object is not callable
127.0.0.1 - - [30/Nov/2016 21:15:28] "GET /todo/1 HTTP/1.1" 500 -
If you want to query Todo by primary key and only return one record you can use:
from flask import jsonify
#app.route('/todo/<int:todo_ID>', methods = ['GET'])
def get(todo_ID):
response = {}
todo = Todo.query.get(todo_ID)
response['id'] = todo.id
response['user_id'] = todo.UserID
response['details'] = todo.details
response['status_code'] = 201
return jsonify(response)
Or you can use Marshmallow to have a serializer for each of your models so it can serialize them for you automatically.
Not sure I understand your problem, if your intention is to return json output as response and you want to control the status code, you could
use jsonify
from flask import jsonify
#app.route('/todo/<int:todo_ID>', methods = ['GET'])
def get(todo_ID):
query = Todo.query("select * from Todo")
response = {'todo': [dict(zip(tuple(query.keys()), i)) for i in query.cursor if i[1] == todo_ID]}
response = jsonify(response)
response.status_code = 201
return response
I have a profile page for my users where they should be able to update their information. For now they can update their names but I also want phonenumbers, addresses, etc.
The code for updating the name of my user is
class AccountPage(BaseRequestHandler):
def get(self):
self.render('accountpage.html', {'request': self.request, 'user': self.current_user,'loggedin': self.logged_in, 'session': self.auth.get_user_by_session(),})
def post(self):
user = self.current_user
user.name = self.request.POST['name']
user.put()
self.auth.set_session(
self.auth.store.user_to_dict(user))
self.render('accountpage.html', {'request': self.request, 'loggedin': self.logged_in,'user': self.current_user})
But how can I use extra variables such as phonenumbers, address variable etc? The webapp2 User model is an expando model. It did not work to just add the variables to the model:
class User(model.Expando):
"""Stores user authentication credentials or authorization ids."""
#: The model used to ensure uniqueness.
unique_model = Unique
#: The model used to store tokens.
token_model = UserToken
created = model.DateTimeProperty(auto_now_add=True)
updated = model.DateTimeProperty(auto_now=True)
# ID for third party authentication, e.g. 'google:username'. UNIQUE.
auth_ids = model.StringProperty(repeated=True)
# Hashed password. Not required because third party authentication
# doesn't use password.
password = model.StringProperty()
phonenumber = model.StringProperty()
address = model.StringProperty()
I use simpleauth and I get this error msg from simpleauth:
INFO 2015-07-20 06:09:34,426 authhandlers.py:78] user_dict | {'name': u'DAC', 'user_id': 5620703441190912, 'token': u'c9BbE72EmrgTDpG1Dl4tlo', 'token_ts': 1437371676, 'cache_ts': 1437371676, 'remember': 0}
ERROR 2015-07-20 06:09:34,437 authhandlers.py:42] 'phonenumber'
INFO 2015-07-20 06:09:34,445 module.py:812] default: "POST /account/ HTTP/1.1" 404 -
INFO 2015-07-20 06:09:34,501 module.py:812] default: "GET /favicon.ico HTTP/1.1" 200 450
In my BaseRequestHandler I have this cached_property that creates an object.
#webapp2.cached_property
def current_user(self):
"""Returns currently logged in user"""
user_dict = self.auth.get_user_by_session()
logging.info('user_dict | %s ' % user_dict)
if user_dict:
return self.auth.store.user_model.get_by_id(user_dict['user_id'])
else:
return api.users.get_current_user()
Then I tried changing the user model but I still get the ERR phone_number when making these changes.
class BaseRequestHandler(webapp2.RequestHandler):
class User(auth_models.User):
address = ndb.StringProperty(indexed=False)
phone_number = ndb.IntegerProperty(indexed=False)
def dispatch(self):
# Get a session store for this request.
self.session_store = sessions.get_store(request=self.request)
if self.request.host.find('.br') > 0:
i18n.get_i18n().set_locale('pt-br')
elif self.request.host.find('klok') > 0:
i18n.get_i18n().set_locale('sv')
elif self.request.host.find('business') > 0:
i18n.get_i18n().set_locale('en')
else:
lang_code_get = self.request.get('hl', None)
if lang_code_get is None:
lang_code = self.session.get('HTTP_ACCEPT_LANGUAGE', None)
lang_code_browser = os.environ.get('HTTP_ACCEPT_LANGUAGE')
if lang_code:
i18n.get_i18n().set_locale(lang_code)
if lang_code_browser and lang_code is None:
self.session['HTTP_ACCEPT_LANGUAGE'] = lang_code_browser
i18n.get_i18n().set_locale(lang_code_browser)
else:
i18n.get_i18n().set_locale(lang_code_get)
try:
# Dispatch the request.
logging.info('trying to dispatch')
webapp2.RequestHandler.dispatch(self)
except Exception, ex:
logging.error(ex)
self.error(404)
finally:
# Save all sessions.
self.session_store.save_sessions(self.response)
#webapp2.cached_property
def jinja2(self):
"""Returns a Jinja2 renderer cached in the app registry"""
return jinja2.get_jinja2(app=self.app)
#webapp2.cached_property
def session(self):
"""Returns a session using the default cookie key"""
return self.session_store.get_session()
#webapp2.cached_property
def auth(self):
return auth.get_auth()
#webapp2.cached_property
def session_store(self):
return sessions.get_store(request=self.request)
#webapp2.cached_property
def auth_config(self):
"""
..........Dict to hold urls for login/logout
......"""
return {'login_url': self.uri_for('login'),
'logout_url': self.uri_for('logout')}
#webapp2.cached_property
def current_user(self):
"""Returns currently logged in user"""
user_dict = self.auth.get_user_by_session()
logging.info('user_dict | %s ' % user_dict)
if user_dict:
return self.auth.store.user_model.get_by_id(user_dict['user_id'])
else:
return api.users.get_current_user()
As mentioned in the comment above - you should NOT be making any changes in any of the built-in libraries, instead, you can extend them and then add any additional code/properties you need.
So first, you'd need to define your own User model, which would look simmilar to this:
from google.appengine.ext import ndb
import webapp2_extras.appengine.auth.models as auth_models
class User(auth_models.User):
address = ndb.StringProperty(indexed=False)
phone_number = ndb.IntegerProperty(indexed=False)
You are only adding the new properties you need or the ones you need to override, so no created / updated / etc as they're inherited from the model you were referring to.
You then need to work with this model inside your BaseRequestHandler class (I'm not sure what the line self.current_user does, you might need to include the code for that as well).
You can also read this article to get some more ideas: http://gosurob.com/post/20024043690/gaewebapp2accounts
I am working off of a Miguel Grinberg tutorial on social authentication.
On the homepage template I have this code, and I removed the twitter portion from the tutorial:
<h2>I don't know you!</h2>
<p>Login with Facebook</p>
{% endif %}
So when you click that link, you pass Facebook as the provider through this view function:
#app.route('/authorize/<provider>')
def oauth_authorize(provider):
if not current_user.is_anonymous():
return redirect(url_for('index'))
oauth = OAuthSignIn.get_provider(provider)
return oauth.authorize()
Now, in a different file, oauth.py, I have the following and my issue is this. I keep getting an error when I click the Facebook link UNLESS the TwitterSignIn class is removed. I guess I am curious as to why the TwitterSignIn class needs to be removed for this to work, because no data is being passed to it, right? Even if Facebook wasn't the only option, why would clicking the Facebook sign-in link pass any data to the TwitterSignIn class?
from rauth import OAuth1Service, OAuth2Service
from flask import current_app, url_for, request, redirect, session
class OAuthSignIn(object):
providers = None
def __init__(self, provider_name):
self.provider_name = provider_name
credentials = current_app.config['OAUTH_CREDENTIALS'][provider_name]
self.consumer_id = credentials['id']
self.consumer_secret = credentials['secret']
def authorize(self):
pass
def callback(self):
pass
def get_callback_url(self):
return url_for('oauth_callback', provider=self.provider_name,
_external=True)
#classmethod
def get_provider(self, provider_name):
if self.providers is None:
self.providers = {}
for provider_class in self.__subclasses__():
provider = provider_class()
self.providers[provider.provider_name] = provider
return self.providers[provider_name]
class FacebookSignIn(OAuthSignIn):
def __init__(self):
super(FacebookSignIn, self).__init__('facebook')
self.service = OAuth2Service(
name='facebook',
client_id=self.consumer_id,
client_secret=self.consumer_secret,
authorize_url='https://graph.facebook.com/oauth/authorize',
access_token_url='https://graph.facebook.com/oauth/access_token',
base_url='https://graph.facebook.com/'
)
def authorize(self):
return redirect(self.service.get_authorize_url(
scope='email',
response_type='code',
redirect_uri=self.get_callback_url())
)
def callback(self):
if 'code' not in request.args:
return None, None, None
oauth_session = self.service.get_auth_session(
data={'code': request.args['code'],
'grant_type': 'authorization_code',
'redirect_uri': self.get_callback_url()}
)
me = oauth_session.get('me').json()
return (
'facebook$' + me['id'],
me.get('email').split('#')[0], # Facebook does not provide
# username, so the email's user
# is used instead
me.get('email')
)
class TwitterSignIn(OAuthSignIn):
def __init__(self):
super(TwitterSignIn, self).__init__('twitter')
self.service = OAuth1Service(
name='twitter',
consumer_key=self.consumer_id,
consumer_secret=self.consumer_secret,
request_token_url='https://api.twitter.com/oauth/request_token',
authorize_url='https://api.twitter.com/oauth/authorize',
access_token_url='https://api.twitter.com/oauth/access_token',
base_url='https://api.twitter.com/1.1/'
)
def authorize(self):
request_token = self.service.get_request_token(
params={'oauth_callback': self.get_callback_url()}
)
session['request_token'] = request_token
return redirect(self.service.get_authorize_url(request_token[0]))
def callback(self):
request_token = session.pop('request_token')
if 'oauth_verifier' not in request.args:
return None, None, None
oauth_session = self.service.get_auth_session(
request_token[0],
request_token[1],
data={'oauth_verifier': request.args['oauth_verifier']}
)
me = oauth_session.get('account/verify_credentials.json').json()
social_id = 'twitter$' + str(me.get('id'))
username = me.get('screen_name')
return social_id, username, None # Twitter does not provide email
Some additional information-
The specific error is this:
File "/Users/metersky/code/mylastapt/app/oauth.py", line 29, in get_provider
provider = provider_class()
File "/Users/metersky/code/mylastapt/app/oauth.py", line 73, in __init__
super(TwitterSignIn, self).__init__('twitter')
File "/Users/metersky/code/mylastapt/app/oauth.py", line 10, in __init__
credentials = current_app.config['OAUTH_CREDENTIALS'][provider_name]
KeyError: 'twitter'
And this is where the I think the issue might be happening:
app.config['OAUTH_CREDENTIALS'] = {
'facebook': {
'id': 'XXX',
'secret': 'XXXX'
}
}
The problem is in OAuthSignIn.get_provider.
#classmethod
def get_provider(self, provider_name):
if self.providers is None:
self.providers = {}
for provider_class in self.__subclasses__():
provider = provider_class()
self.providers[provider.provider_name] = provider
return self.providers[provider_name]
The first time you call it from within your view
oauth = OAuthSignIn.get_provider(provider)
the method caches the providers you've defined. It does this by checking for all of OAuthSignIn's subclasses.
for provider_class in self.__subclasses__():
When you include TwitterSignIn, it will be included as a subclass. You'll then instantiate an instance of the class
provider = provider_class()
Inside OAuthSignIn.__init__, you load the provider's settings with current_app.config['OAUTH_CREDENTIALS'][provider_name]. Since Twitter isn't included, you get the KeyError.
If you don't want to support Twitter, just remove the class. If you want to protect your application a little more so that providers can be removed from your settings without updating code, you'll need to check for the exception. You could do the check inside OAuthSignIn.__init__, but there probably isn't much value to including an unsupported provider in OAuthSignIn.providers. You're better off putting the check in OAuthSignIn.get_provider.
#classmethod
def get_provider(cls, provider_name):
if cls.providers is None:
cls.providers = {}
for provider_class in cls.__subclassess__():
try:
provider = provider_class()
except KeyError:
pass # unsupported provider
else:
cls.providers[provider.provider_name] = provider
return cls.providers[provider_name]
I am running into what appears to be a Python error on Google App Engine (localhost)
I am trying to use the Model.get_by_id() function but I run into a multiple keyword arguments error as I've pointed out in the comment in the code below. 3rd line from the bottom
I'm sure this is simple error, I just can't see it.
Thanks in advance!
'''
Created on 09/01/2013
#author: jonathan
'''
import webapp2_extras.security as security
from google.appengine.ext import db
import hashlib
import datetime
class User(db.Model):
username = db.StringProperty(required=True)
passhash = db.StringProperty(required=True)
email = db.EmailProperty()
created = db.DateTimeProperty(auto_now_add=True)
authtoken = db.StringProperty(required=True)
def __init__(self, username, password, email=None):
authtoken = security.generate_random_string(entropy=256)
passhash = security.generate_password_hash(password)
super(User, self).__init__(username=username,
passhash=passhash,
email=email,
authtoken=authtoken)
def __str__(self):
return self.username
def check_password(self, password):
return security.check_password_hash(password, self.passhash)
#classmethod
def check_unique_user(cls, username):
return not bool(cls.all().filter('username =', username).count())
def get_session_token(self, dt=None):
ID = self.key().id()
if not dt:
dt = datetime.datetime.now().strftime("%d%m%y%H%M%S")
hashstring = "{0}${1}${2}".format(ID, dt, self.authtoken)
return '{0}${1}${2}'.format(ID, dt, hashlib.sha256(hashstring).hexdigest())
#classmethod
def check_session_token(cls, session_token):
if session_token:
ID, dt = session_token.split("$")[:2]
if ID.isdigit():
user = cls.get_by_id(ids=int(ID)) # Raises TypeError: __init__() got multiple values for keyword argument 'username'
if user and user.check_session_token(session_token, dt):
return user
The rest of my code:
common.py #This one is still a work in progress...
'''
Created on 06/01/2013
#author: jonathan
'''
import os
import webapp2
import jinja2
template_dir = os.path.join(os.path.dirname(__file__), 'templates')
jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_dir),
autoescape=True)
class Handler(webapp2.RedirectHandler):
def write(self, *args, **kwargs):
self.response.out.write(*args, **kwargs)
def render_str(self, template, **params):
templated_html = jinja_env.get_template(template)
return templated_html.render(params)
def render(self, template, **kwargs):
self.write(self.render_str(template, **kwargs))
if os.environ['SERVER_SOFTWARE'].startswith('Development'):
app_scheme = 'http'
else:
app_scheme = 'https'
registration.py
'''
Created on 07/01/2013
#author: jonathan
'''
import common
from webapp2_extras.routes import RedirectRoute
import re
from models.user import User
def getroutes():
return [RedirectRoute(r'/signup', handler=SignupPage, name='signup', schemes=common.app_scheme, strict_slash=True),
(RedirectRoute(r'/welcome', handler=WelcomePage, name='welcome', strict_slash=True)),
(RedirectRoute(r"/login", handler=LoginPage, name="login", schemes=common.app_scheme, strict_slash=True)),
(RedirectRoute(r'/logout', handler=LogoutPage, name="logout", strict_slash=True))]
username_pattern = re.compile(r"^[a-zA-Z0-9_-]{3,20}$")
password_pattern = re.compile(r"^.{3,20}$")
email_pattern = re.compile("^[\S]+#[\S]+\.[\S]+$")
def valid_username(username):
return username_pattern.match(username)
def valid_password(password):
return password_pattern.match(password)
def verify_password(password, verify):
return password == verify
def valid_email(email):
return email_pattern.match(email)
class SignupPage(common.Handler):
def render(self, **kwargs):
super(SignupPage, self).render("signup.html", **kwargs)
def get(self):
session_token = self.request.cookies.get("session")
if User.check_session_token(session_token):
self.redirect_to("welcome")
self.render()
def post(self):
v_username = v_password = v_email = False
username = self.request.get("username")
password = self.request.get("password")
verify = self.request.get("verify")
email = self.request.get("email")
params = {'username_error':'',
'password_error':'',
'verify_error':'',
'email_error':'',
'username':username,
'email':email}
if valid_username(username):
if User.check_unique_user(username):
v_username = True
else:
params['username_error'] = "Username taken"
else:
params['username_error'] = "Invalid username"
if valid_password(password):
if verify_password(password, verify):
v_password = True
else:
params['verify_error'] = "Passwords do not match"
else:
params['password_error'] = "Invalid password"
if valid_email(email):
v_email = True
else:
params['email_error'] = "Invalid email"
if v_username and v_password:
if v_email:
user = User(username=username,
password=password,
email=email)
else:
user = User(username=username,
password=password)
user.put()
session_token = user.get_session_token()
self.response.set_cookie("session", session_token)
self.redirect(r'/welcome')
else:
self.render(**params)
class WelcomePage(common.Handler):
def get(self):
session_token = self.request.cookies.get("session")
user = User.check_session_token(session_token)
if not user:
self.response.delete_cookie('session')
self.redirect_to("signup")
else:
self.render("welcome.html", {'user':user})
class LoginPage(common.Handler):
def get(self):
session_token = self.request.cookies.get("session")
user = User.check_session_token(session_token)
if not user:
self.response.delete_cookie('session')
self.redirect_to("signup")
else:
self.render("login.html")
def post(self):
username = self.request.get('username')
password = self.request.get('password')
remember = self.request.get('remember')
params = {}
user = None
if valid_username(username):
user = User.all().filter('username =', username).get()
if not user:
params['username_error'] = "Can't find username"
else:
params['username_error'] = "Invalid username"
if user and user.check_password(password):
self.redirect_to('welcome')
else:
params['password_error'] = "Mismatched password"
self.render('login.html', params)
class LogoutPage(common.Handler):
def get(self):
self.response.delete_cookie("session")
self.redirect(r'/signup')
You likely have an instance of User in your datastore where "username" is not a StringProperty, but a list. When the db library fetches the entity and parses it, it's unable to convert the list into a StringProperty.
I'd suggest using the datastore viewer and checking that your entities actually have valid Strings for the username.
Edit: Just looked through the code again. It's a very bad idea to override init. The User class is not a typical class, but rather it's a metaclass for generate User instances. ie, your User instances are not actually instances of your user class. I suspect you're running into an issue there.