I've run into a bit of a snag on this code and could use some help, I can't manage to figure out what is the issue here.
File "C:\Users\Joshua\Desktop\sasquatch_sightings\flask_app\controllers\users.py", line 34, in user_dashboard
return render_template("dashboard.html",user=User.get_user_by_id(data),sightings=Sighting.get_all())
File "C:\Users\Joshua\Desktop\sasquatch_sightings\flask_app\models\user.py", line 44, in get_user_by_id
return cls(results[0])
IndexError: tuple index out of range
My Code
Users.py
from flask_app import app
from flask import render_template, redirect, request, session, flash
from flask_app.models.user import User
from flask_app.models.sighting import Sighting
from flask_bcrypt import Bcrypt
bcrypt = Bcrypt(app)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/user/create', methods={'POST'})
def create_user():
if not User.validate_user_reg_data(request.form):
return redirect('/')
data = {
"first_name": request.form['first_name'],
"last_name": request.form['last_name'],
"email": request.form['email'],
"password": bcrypt.generate_password_hash(request.form['password'])
}
id = User.create_user(data)
session['user_id'] = id
return redirect('/user/dashboard')
#app.route('/user/dashboard')
def user_dashboard():
if 'user_id' not in session:
return redirect('/logout')
data = {
'id': session ['user_id']
}
return render_template("dashboard.html",user=User.get_user_by_id(data),sightings=Sighting.get_all())
#app.route('/user/login', methods = ['POST'])
def login():
user = User.get_user_by_email(request.form)
if not user:
flash("Invalid Email, login")
return redirect('/')
session['user_id'] = user.id
return redirect('/user/dashboard')
#app.route('/user/logout')
def logout():
session.clear()
return redirect('/')
2nd Code User.py
from flask_app.config.mysqlconnection import MySQLConnection, connectToMySQL
from flask import flash, session
import re
EMAIL_REGEX = re.compile(r'^[a-zA-Z0-9.+_-]+#[a-zA-Z0-9._-]+\.[a-zA-Z]+$')
class User:
db = "sasquatch"
def __init__(self,data):
self.id = data['id']
self.first_name = data['first_name']
self.last_name = data['last_name']
self.email = data['email']
self.password = data['password']
self.created_at = data['created_at']
self.updated_at = data['updated_at']
#classmethod
def create_user(cls, data):
data = cls.parse_registration_data(data)
query = "INSERT INTO users (first_name, last_name, email, password) VALUES (%(first_name)s, %(last_name)s, %(email)s, %(password)s);"
return connectToMySQL(cls.db).query_db(query, data)
#classmethod
def get_all(cls):
query = "SELECT * FROM users;"
results = connectToMySQL(cls.db).query_db(query)
users = []
for row in results:
users.append( cls(row))
return users
#classmethod
def get_user_by_email(cls, data):
query = "SELECT * FROM users WHERE email = %(email)s;"
results = connectToMySQL(cls.db).query_db(query,data)
if len(results) < 1:
return False
return cls(results[0])
#classmethod
def get_user_by_id(cls,data):
query = "SELECT * FROM users WHERE id = %(id)s;"
results = connectToMySQL(cls.db).query_db(query,data)
return cls(results[0])
#staticmethod
def validate_user_reg_data(user):
is_valid = True
query = "SELECT * FROM users WHERE email = %(email)s;"
results = connectToMySQL(User.db).query_db(query,user)
if len(results) >= 1:
flash("Email already taken.","register")
is_valid=False
if not EMAIL_REGEX.match(user['email']):
flash("Invalid Email","register")
is_valid=False
if len(user['first_name']) < 2:
flash("First name must be more than 2 characters","register")
is_valid= False
if len(user['last_name']) < 2:
flash("Last name must be more than 2 characters", "register")
if len(user['password']) < 8:
flash("Password must be more than 8 characters","register")
is_valid= False
if user['password'] != user['confirm']:
flash("Passwords do not match","register")
return is_valid
#staticmethod
def parse_registration_data(data):
parsed_data = {}
parsed_data['email'] = data['email'].lower()
parsed_data['first_name'] = data['first_name']
parsed_data['last_name'] = data['last_name']
return parsed_data
Related
I'm working on fastapi web app and currently strugling with one thing.
I'm working on google auth system and my dependency injection does not work as expected.
Here are my endpoints:
#app.route('/login')
async def login(request: Request):
redirect_uri = request.url_for('auth')
return await oauth.google.authorize_redirect(request, redirect_uri)
#app.route('/auth')
async def auth(request: Request):
try:
access_token = await oauth.google.authorize_access_token(request)
except OAuthError as e:
raise CREDENTIALS_EXCEPTION
_data = access_token["userinfo"]
if get_or_create_user(data = _data):
return JSONResponse({'result': True, 'access_token': create_token(_data['email'])})
raise CREDENTIALS_EXCEPTION
The problem lies in get_or_create_user function.
#validate_payload
def get_or_create_user(data: USER_GOOGLE_DATA, users_repo: UsersRepository = Depends(SQLUsersRepository)) -> model.User:
_email: str = data.get("email")
if not _email:
raise AttributeError("Payload is missing data")
user: model.User = users_repo.get_by_email(email=_email)
if not user:
_user = model.User(**dict(data))
user = users_repo.add(model.User(_user))
return user
data is dict with required info to create user and users_repo is crud class. Decorator is just to check if data contains all required keys.
PAYLOAD_KEYS: Tuple[str] = ("email",)
def validate_payload(func: Callable[[USER_GOOGLE_DATA, UsersRepository], model.User]):
def decorator(*args, **kwargs):
_data: USER_GOOGLE_DATA = kwargs.get("data")
for _key in PAYLOAD_KEYS:
if _key not in _data:
return None
return func(_data)
return decorator
My crud class looks like following:
class SQLUsersRepository(input_boundries.UsersRepository):
def __init__(self, db: Session or RawDBConnection = Depends(get_db)):
self._db = db
def get(self, user_id: UserId) -> model.User:
user_db = self._db.query(model.User).filter(model.User.id == user_id).first()
if not user_db:
raise DBRecordNotFound(f"User with id: '{user_id}' not found.")
return user_db
def get_by_email(self, email: str) -> model.User:
user_db = self._db.query(model.User).filter(model.User.email == email).first()
if not user_db:
raise DBRecordNotFound(f"User with email: '{email}' not found.")
return user_db
def add(self, user: model.User) -> model.User:
self._db.add(user)
self._db.commit()
self._db.refresh(user)
return user
def save(self, user: model.User) -> None:
user_db = self._db.query(model.User).filter(model.User.id == user.id).first()
self.add(user=user_db)
def remove(self, user_id: UserId) -> None:
user_db = self._db.query(model.User).filter(model.User.id == user_id).first()
if not user_db:
raise DBRecordNotFound(f"User with id: '{user_id}' not found.")
user_db.delete()
self._db.commit()
The error I receive AttributeError: 'Depends' object has no attribute 'get_by_email'
What's wrong with these dependiences? As far as I remember Depends() works similar to decorator (it triggers first).
I am using Django and PostgreSQL (psycopg2) for one of our web REST API projects.
Basically, the app is driven by the django-rest-framework library for all REST API-centric tasks such as authentication, permission, serialization and API views. However, since our database tables are not created thru Django's migration system (rather created manually and directly thru DBeaver), our modeling and serialization can actually be considered as highly customized and is no longer following Django's ORM standard (although we try to write our custom ORM design to feel as close as Django's as possible so that the pattern will still feel familiar).
The way I communicate CRUD actions to and from the database is by creating one (1) custom manager class mapped to each custom model class that it's supposed to manage. So in my manager I have like get(), insert(), update(), delete(), force_delete() methods which contain logic for actually sending queries to the database.
For all methods responsible for fetching data i.e. get() all() filter(), they communicate through a database view instead of directly sending a query to the concerned table that may contain JOINs which may be too expensive for the DB server.
This design works fine for us, but I still ask myself if this is actually ideal or at least an acceptable approach specially on real-world, daily consumption of our API by potentially millions of clients.
Or is there any best practice which I should strictly follow? Or any better approach anyone may suggest?
Here are the sample classes for one of our API resources - API version:
DB table
Model Class
class ApiVersionModel:
objects = ApiVersionManager()
def __init__(self):
self.version = None
self.version_info = None
self.date_released = None
self.development = None
self.production = None
def save(self, initial=False):
if not initial:
self.objects.update(self)
else:
self.objects.insert(self)
def delete(self, force_delete=False):
if force_delete:
self.objects.delete(self)
else:
self.objects.soft_delete(self)
Serializer Class
class ApiVersionSerializer(serializers.Serializer):
version = serializers.CharField(max_length=15)
version_info = serializers.CharField(max_length=255, required=False, allow_null=True)
date_released = serializers.DateField()
development = serializers.BooleanField(default=True, required=False, allow_null=True)
production = serializers.BooleanField(default=False, required=False, allow_null=True)
def create(self, validated_data):
c = ApiVersionModel()
c.version = validated_data.get("version")
c.version_info = validated_data.get("version_info")
c.date_released = validated_data.get("date_released")
c.development = validated_data.get("development")
c.production = validated_data.get("production")
c.save(initial=True)
return c
def update(self, c, validated_data):
c.version = validated_data.get("version")
c.version_info = validated_data.get("version_info")
c.date_released = validated_data.get("date_released")
c.development = validated_data.get("development")
c.production = validated_data.get("production")
c.save()
return c
def delete(self, c, validated_data, force_delete=False):
c.version = validated_data.get("version")
c.version_info = validated_data.get("version_info")
c.date_released = validated_data.get("date_released")
c.development = validated_data.get("development")
c.production = validated_data.get("production")
c.delete(force_delete=force_delete)
return c
Manager Class
import traceback
from config.utils import (raw_sql_select, raw_sql_select_enhanced, raw_sql_insert, raw_sql_update, raw_sql_delete)
from unit2_app.utils.ModelUtil import where
class ApiVersionManager():
def __init__(self):
pass
#staticmethod
def all(**kwargs):
query = None
x = None
where_clause = where(**kwargs)
query = ("""
SELECT *
FROM sample_schema.api_version {};
""".format(where_clause))
x = raw_sql_select_enhanced(query, "slave", list(kwargs.values()))
if x is not None:
objects = []
from unit2_app.models.Sys import ApiVersionModel
for col in x[1]:
c = ApiVersionModel()
c.version = col.version
c.version_info = col.version_info
c.date_released = col.date_released
c.development = col.development
c.production = col.production
objects.append(c)
return [] if len(objects) == 0 else objects
return []
#staticmethod
def get(**kwargs):
query = None
x = None
where_clause = where(**kwargs)
query = ("""
SELECT *
FROM sample_schema.api_version {};
""".format(where_clause))
x = raw_sql_select_enhanced(query, "slave", list(kwargs.values()))
if x is not None:
objects = []
from unit2_app.models.Sys import ApiVersionModel
for col in x[1]:
c = ApiVersionModel()
c.version = col.version
c.version_info = col.version_info
c.date_released = col.date_released
c.development = col.development
c.production = col.production
objects.append(c)
return None if len(objects) == 0 else objects[0]
return None
#staticmethod
def filter(**kwargs):
query = None
x = None
where_clause = where(**kwargs)
query = ("""
SELECT *
FROM sample_schema.api_version {};
""".format(where_clause))
x = raw_sql_select_enhanced(query, "slave", list(kwargs.values()))
if x is not None:
objects = []
from unit2_app.models.Sys import ApiVersionModel
for col in x[1]:
c = ApiVersionModel()
c.version = col.version
c.version_info = col.version_info
c.date_released = col.date_released
c.development = col.development
c.production = col.production
objects.append(c)
return [] if len(objects) == 0 else objects
return []
#staticmethod
def insert(c):
try:
query = ("""
START TRANSACTION;
INSERT INTO sample_schema.api_version
(version, version_info, date_released, development, production)
VALUES (%(version)s, %(version_info)s, %(date_released)s, %(development)s, %(production)s);
""")
raw_sql_insert(query, "master", c.__dict__)
except Exception:
traceback.print_exc()
raise Exception("Unexpected manager exception has been encountered.")
#staticmethod
def update(c):
try:
query = ("""
START TRANSACTION;
UPDATE sample_schema.api_version SET
version_info = %(version_info)s,
date_released = %(date_released)s,
development = %(development)s,
production = %(production)s
WHERE version = %(version)s;
""")
raw_sql_update(query, "master", c.__dict__)
except Exception:
raise Exception("Unexpected manager exception has been encountered.")
#staticmethod
def delete(c):
try:
print(c.__dict__)
query = ("""
START TRANSACTION;
DELETE FROM sample_schema.api_version WHERE version=%(version)s;
""")
raw_sql_delete(query, "master", c.__dict__)
except Exception:
raise Exception("Something went wrong with the database manager.")
#staticmethod
def soft_delete(c):
pass
API View Class
class APIView_ApiVersion(views.APIView):
try:
serializer_class = ApiVersionSerializer
permission_classes = (IsAuthenticatedOrReadOnly,)
authentication_classes = ()
except:
traceback.print_exc()
def get_queryset(self, **fltr):
return self.serializer_class(ApiVersionModel.objects.all(**fltr), many=True).data
def get(self, request, **kwargs):
try:
fltr = {k:v[0] for k,v in dict(self.request.GET).items()}
return_data = None
url_path_param_version = None
return_data = self.get_queryset(**fltr)
# perform filtering for version if <version> path param
# ... is present in the URL
if request.resolver_match.kwargs and request.resolver_match.kwargs["version"]:
url_path_param_version = request.resolver_match.kwargs["version"]
return_data = ApiVersionModel.objects.get(version=url_path_param_version, **fltr)
else:
return_data = ApiVersionModel.objects.all(**fltr)
if isinstance(return_data, list):
if len(return_data) > 0:
return Response({
"success": True,
"message": "API version has been fetched successfully.",
"data": self.serializer_class(return_data, many=True).data
}, status=status.HTTP_200_OK)
else:
return Response({
"success": True,
"message": HTTPNotFound.resource_empty(None, obj="API version"),
"data": []
}, status=status.HTTP_200_OK)
else:
if return_data:
return Response({
"success": True,
"message": "API version has been fetched successfully.",
"data": self.serializer_class(return_data).data
}, status=status.HTTP_200_OK)
else:
return Response({
"success": False,
"message": HTTPNotFound.object_unknown(None, obj="API version")
}, status=HTTPNotFound.status_code)
except Exception as e:
return Response({
"success": False,
"message": str(HTTPServerError.unknown_error(None)) + " DETAIL: {}".format(str(e))
}, status=HTTPServerError.status_code)
# Other METHODS also go here i.e. post(), update(), etc.
Custom utility for dynamic API resource filtering / dynamic WHERE CLAUSE
Since our ORM is highly customized, it hinders us from using DRF's inbuilt filtering classes. So I created my own simple utility to optionally allow filtering of SELECT queries via a query string. When applied, the value that the where() method generates gets injected into the DB query in our custom managers.
def filter(key, val):
f = []
c = ""
operator = "="
if len(key.split('__')) > 1:
dus = key.split('__')
for x in range(len(dus)):
f.append(str('{}' if x == 0 else "'{}'").format(dus[x]))
else:
f.append(key)
c = c.join(f) + " {} {} ".format(operator, str(val))
if len(key.split('___')) > 1:
tus = key.split('___')
for x in range(len(tus)):
if tus[x] == "lt":
operator = "<"
elif tus[x] == "lte":
operator = "<="
elif tus[x] == "gt":
operator = ">"
elif tus[x] == "gte":
operator = ">="
for y in f:
if tus[x] in y:
f.remove(y)
y = ""
if len(f) > 2:
for x in range(len(f)):
if x < len(f)-2:
y += f[x] + "->"
elif x <= len(f)-2:
y += f[x] + "->>"
elif x >= len(f)-2:
y += f[x]
else:
y += "->>".join(f)
if val is not None:
if isinstance(val, bool):
c = y + " {} '{}' ".format(operator, str(val).lower())
else:
c = y + " {} '{}' ".format(operator, str(val))
else:
c = y + " IS NULL "
return c
def where(**kwargs):
fields = []
if bool(kwargs):
for key, val in kwargs.items():
# fields.append(filter_nest(key, val))
fields.append(filter(key,val))
return ' WHERE ' + ' AND '.join(fields) if bool(kwargs) else ""
class account(object):
__duser_id = ''
__duser_name =''
__duser_no = ''
def __init__(self, default, entry_name, password, user_id='', user_name='', user_no=''):
if type(default) != bool:
raise Exception("Error 0x1: type(default) is boolean ")
if default == False:
self.__user_id = user_id
self.__user_name = user_name
self.__user_no = user_no
else:
self.__user_id = __duser_id
self.__user_name = __duser_name
self.__user_no = __duser_no
self.__entry_name = entry_name
self.__password = password
def dset(self, duser_id=__duser_id, duser_name=__duser_name, duser_no=__duser_no):
__duser_id = duser_id
__duser_name = duser_name
__duser_no = duser_no
return (__duser_id, __duser_name, __duser_no)
def dget(self):
return (__duser_id, __duser_name, __duser_no)
def set(self, user_name=self.__user_name, user_id=self.__user_id, user_no=self.__user_no, password=self.__password):
self.__user_id = user_id
self.__user_name = user_name
self.__user_no = user_no
self.__password = password
return (self.__user_id, self.__user_name, self.__user_no, self.password)
def get(self):
return (self.__user_id, self.__user_name, self.__user_no, self.password)
if __name__ == '__main__':
gmail = account(default=True, entry_name='gmail', password='pass***')
print(gmail.dget())
print(gmail.get())
out put is:
Traceback (most recent call last):
File "interface.py", line 1, in
class account(object):
File "interface.py", line 30, in account
def set(self, user_name=self.__user_name, user_id=self.__user_id, user_no=self.__user_no, password=self.__password):
NameError: name 'self' is not defined
Ok o got it.
but there is another one i just changed code.
This is a decorator with arbitrary number of arguments and keyword
arguments
def user_no_is_number(func):
def wrapper(*args, **kargs):
if 'user_no' in kargs:
if type(kargs['user_no']) != int:
raise Exception('Error 1x0: user_no must contains only numbers.')
else:
return func(*args, **kargs)
return wrapper
#staticmethod
#user_no_is_number
def dset(user_id=None, user_name=None, user_no=None):
if user_id:
account.__duser_id = user_id
if user_name:
account.__duser_name = user_name
if user_no:
account.__duser_no = user_no
return (account.__duser_id, account.__duser_name, account.__duser_no)
but the dset() function return always None
*I think there is problem with arbitrary keywords parameters. by using **kargs in decorator parameter it becomes dictionary and by again passing **kargs it just return values of that dictionary.*
I am working with Google App Engine and using the datastore to create a table for Users containing the entities username, the hash of the password, the email and the date joined. But when I run a function to register a user the function that hashes the passwords is returning the NoneType error.
I tried to look for the error, but the form is posting the values and I am able to get them from the headers.
This is the piece of code that handles the registration
def make_salt():
chars = string.ascii_uppercase + string.ascii_lowercase + string.ascii_digits
return ''.join(random.choice(chars) for x in range(5))
def make_pw_h(name, pw, salt = None):
if salt:
salt = make_salt()
return "%s,%s" % (salt, hashlib.sha256(name + pw + salt).hexdigest())
def check_pw_h(name, pw, h):
h = h.split(',')[1]
return h == make_pw_h(name, pw, h)
class Users(db.Model):
username = db.StringProperty(required = True)
pw_hash = db.StringProperty(required = True)
emai = db.StringProperty()
user_since = db.DateTimeProperty(auto_now_add = True)
#classmethod
def by_id(cls, uid):
return Users.get_by_id(uid)
#classmethod
def by_name(cls, name):
user = Users.all().filter('name = ', name).get()
return user
#classmethod
def register(cls, name, pw, email = None):
pw_h = make_pw_h(name, pw)
return Users(username = name,
pw_hash = pw_h,
email = email)
#classmethod
def login(cls, name, pw):
u = cls.by_name(name)
if u and check_pw(pw):
return u
def make_secure_val(s):
return '%s|%s' % (val, hmac.new(secret, val).hexdigest())
def check_secure_val(sec_val):
val = val.split('|')[0]
if sec_val == make_secure_val(val):
return val
class BaseHandler(webapp2.RequestHandler):
#this function uses the render_str funcion to display the html form in the browser
def render(self, template, **kw):
self.response.out.write(render_str(template, **kw))
#this funcion is a simple function using the template engine to write out the required data with
#any extra parameters
def write(self, *a, **kw):
self.response.out.write(*a, **kw)
def set_sec_coki(self, name, val):
sec_val = make_secure_val(val)
self.response.headers.add_cookie('Set-Cookie', "%s=%s; Path=/" % (name, sec_val))
def read_sec_coki(self, name):
coki_val = self.request.cookies.get(name)
return coki_val and check_secure_val(coki_val)
def Initialize(self, *a, **kw):
webapp2.RequestHandler.Initialize(self, *a, **kw)
uid = self.read_sec_coki('user-id')
self.user = uid and Users.by_id(int(uid))
class Signup(BaseHandler):
def get(self):
self.render("signup-form.html")
def post(self):
have_error = False
self.username = self.request.get('username')
self.password = self.request.get('password')
self.verify = self.request.get('verify')
self.email = self.request.get('email')
params = dict(username = self.username,
email = self.email)
if not valid_username(self.username):
params['error_username'] = "That's not a valid username."
have_error = True
if not valid_password(self.password):
params['error_password'] = "That wasn't a valid password."
have_error = True
elif self.password != self.verify:
params['error_verify'] = "Your passwords didn't match."
have_error = True
if not valid_email(self.email):
params['error_email'] = "That's not a valid email."
have_error = True
if have_error:
self.render('signup-form.html', **params)
else:
u = Users.by_name(self.username)
if u:
msg = "User already exists"
self.render('signup-form.html', error_username = msg)
else:
sing_user = Users.register(self.username, self.password, self.email)
sing_user.put()
self.login(sing_user)
self.set_sec_coki('user-id', sing_user.key().id())
self.redirect('/welcome')
class WelcomePage(BaseHandler):
def get(self):
coki_val = read_sec_coki('user-id')
u_id = coki_val.check_secure_val(coki_val)
part_usr = u_id.by_id(int(u_id))
name = part_usr.username
self.render("welcome.html", username = name)
And this is the error stack that I am getting when I try to register a new user via the form
Traceback (most recent call last):
File "/home/bigb/google_projects/google_appengine/lib/webapp2/webapp2.py", line 1536, in __call__
rv = self.handle_exception(request, response, e)
File "/home/bigb/google_projects/google_appengine/lib/webapp2/webapp2.py", line 1530, in __call__
rv = self.router.dispatch(request, response)
File "/home/bigb/google_projects/google_appengine/lib/webapp2/webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "/home/bigb/google_projects/google_appengine/lib/webapp2/webapp2.py", line 1102, in __call__
return handler.dispatch()
File "/home/bigb/google_projects/google_appengine/lib/webapp2/webapp2.py", line 572, in dispatch
return self.handle_exception(e, self.app.debug)
File "/home/bigb/google_projects/google_appengine/lib/webapp2/webapp2.py", line 570, in dispatch
return method(*args, **kwargs)
File "/home/bigb/google_projects/my-ramblings/blog.py", line 197, in post
sing_user = Users.register(self.username, self.password, self.email)
File "/home/bigb/google_projects/my-ramblings/blog.py", line 55, in register
pw_h = make_pw_h(name, pw)
File "/home/bigb/google_projects/my-ramblings/blog.py", line 32, in make_pw_h
return "%s,%s" % (salt, hashlib.sha256(name + pw + salt).hexdigest())
TypeError: coercing to Unicode: need string or buffer, NoneType found
You call make_pw_h() with just two arguments, name and pw. You leave salt to the default, None:
def make_pw_h(name, pw, salt = None):
if salt:
salt = make_salt()
return "%s,%s" % (salt, hashlib.sha256(name + pw + salt).hexdigest())
This means the if salt: test is False and you end up with passing None to hashlib.sha256.
Perhaps you meant to test if salt is not set:
def make_pw_h(name, pw, salt=None):
if salt is None:
salt = make_salt()
return "%s,%s" % (salt, hashlib.sha256(name + pw + salt).hexdigest())
I am trying to copy and use the example 'User Authentication with PostgreSQL database' from the web.py cookbook. I can not figure out why I am getting the following errors.
at /login
'ThreadedDict' object has no attribute 'login'
at /login
'ThreadedDict' object has no attribute 'privilege'
Here is the error output to the terminal for the second error. (the first is almost identical)
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/web.py-0.37-py2.7.egg/web/application.py", line 239, in process
return self.handle()
File "/usr/local/lib/python2.7/dist-packages/web.py-0.37-py2.7.egg/web/application.py", line 230, in handle
return self._delegate(fn, self.fvars, args)
File "/usr/local/lib/python2.7/dist-packages/web.py-0.37-py2.7.egg/web/application.py", line 420, in _delegate
return handle_class(cls)
File "/usr/local/lib/python2.7/dist-packages/web.py-0.37-py2.7.egg/web/application.py", line 396, in handle_class
return tocall(*args)
File "/home/erik/Dropbox/Python/Web.py/Code.py", line 44, in GET
render = create_render(session.privilege)
File "/usr/local/lib/python2.7/dist-packages/web.py-0.37-py2.7.egg/web/session.py", line 71, in __getattr__
return getattr(self._data, name)
AttributeError: 'ThreadedDict' object has no attribute 'privilege'
127.0.0.1:36420 - - [25/Aug/2012 01:12:38] "HTTP/1.1 GET /login" - 500 Internal Server Error
Here is my code.py file. Pretty much cut-n-paste from the cookbook. I tried putting all of the class and def on top of the main code. I have also tried launching python with sudo as mentioned in another post.
import web
class index:
def GET(self):
todos = db.select('todo')
return render.index(todos)
class add:
def POST(self):
i = web.input()
n = db.insert('todo', title=i.title)
raise web.seeother('/')
def logged():
return False #I added this to test error #1, Now I get error #2
#if session.login==1:
# return True
#else:
# return False
def create_render(privilege):
if logged():
if privilege == 0:
render = web.template.render('templates/reader')
elif privilege == 1:
render = web.template.render('templates/user')
elif privilege == 2:
render = web.template.render('templates/admin')
else:
render = web.template.render('templates/communs')
else:
render = web.template.render('templates/communs')
return render
class Login:
def GET(self):
if logged():
render = create_render(session.privilege)
return '%s' % render.login_double()
else:
# This is where error #2 is
render = create_render(session.privilege)
return '%s' % render.login()
def POST(self):
name, passwd = web.input().name, web.input().passwd
ident = db.select('users', where='name=$name', vars=locals())[0]
try:
if hashlib.sha1("sAlT754-"+passwd).hexdigest() == ident['pass']:
session.login = 1
session.privilege = ident['privilege']
render = create_render(session.privilege)
return render.login_ok()
else:
session.login = 0
session.privilege = 0
render = create_render(session.privilege)
return render.login_error()
except:
session.login = 0
session.privilege = 0
render = create_render(session.privilege)
return render.login_error()
class Reset:
def GET(self):
session.login = 0
session.kill()
render = create_render(session.privilege)
return render.logout()
#web.config.debug = False
render = web.template.render('templates/', base='layout')
urls = (
'/', 'index',
'/add', 'add',
'/login', 'Login',
'/reset', 'Reset'
)
app = web.application(urls, globals())
db = web.database(dbn='postgres', user='hdsfgsdfgsd', pw='dfgsdfgsdfg', db='postgres', host='fdfgdfgd.com')
store = web.session.DiskStore('sessions')
# Too me, it seems this is being ignored, at least the 'initializer' part
session = web.session.Session(app, store, initializer={'login': 0, 'privilege': 0})
if __name__ == "__main__": app.run()
Okay, I was able to figure out what I did wrong. Total newbie stuff and all part of the learning process. This code now works, well mostly. The part that I was stuck on is now working. See my comments in the code
Thanks
import web
web.config.debug = False
render = web.template.render('templates/', base='layout')
urls = (
'/', 'index',
'/add', 'add',
'/login', 'Login',
'/reset', 'Reset'
)
app = web.application(urls, globals())
db = web.database(blah, blah, blah)
store = web.session.DiskStore('sessions')
session = web.session.Session(app, store, initializer={'login': 0, 'privilege': 0})
class index:
def GET(self):
todos = db.select('todo')
return render.index(todos)
class add:
def POST(self):
i = web.input()
n = db.insert('todo', title=i.title)
raise web.seeother('/')
def logged():
if session.get('login', False):
return True
else:
return False
def create_render(privilege):
if logged():
if privilege == 0:
render = web.template.render('templates/reader')
elif privilege == 1:
render = web.template.render('templates/user')
elif privilege == 2:
render = web.template.render('templates/admin')
else:
render = web.template.render('templates/communs')
else:
## This line is key, i do not have a communs folder, thus returning an unusable object
#render = web.template.render('templates/communs') #Original code from example
render = web.template.render('templates/', base='layout')
return render
class Login:
def GET(self):
if logged():
## Using session.get('something') instead of session.something does not blow up when it does not exit
render = create_render(session.get('privilege'))
return '%s' % render.login_double()
else:
render = create_render(session.get('privilege'))
return '%s' % render.login()
def POST(self):
name, passwd = web.input().name, web.input().passwd
ident = db.select('users', where='name=$name', vars=locals())[0]
try:
if hashlib.sha1("sAlT754-"+passwd).hexdigest() == ident['pass']:
session.login = 1
session.privilege = ident['privilege']
render = create_render(session.get('privilege'))
return render.login_ok()
else:
session.login = 0
session.privilege = 0
render = create_render(session.get('privilege'))
return render.login_error()
except:
session.login = 0
session.privilege = 0
render = create_render(session.get('privilege'))
return render.login_error()
class Reset:
def GET(self):
session.login = 0
session.kill()
render = create_render(session.get('privilege'))
return render.logout()
if __name__ == "__main__": app.run()