GAE counting visitors using cookie - google-app-engine

This codes count the number of time we have visited the page, until browser is closed, using cookies. Which I am not getting. Please help
class MainPage(Handler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
visits = self.request.cookies.get('visits','0')
if visits.isdigit():
visits = int(visits) + 1
else:
visits= 0
self.response.headers.add_header('Set-Cookie', 'visits=%s' %visits)
self.write("you've been here %s times" %visits)
I just want to know what is happening in these two lines
visits = self.request.cookies.get('visits','0')
and
self.response.headers.add_header('Set-Cookie', 'visits=%s' %visits)

Rather than just give you the answer, I'll help you figure out how to get it.
self.request and self.response are properties of the MainPage class. To figure out what these two things are doing you need to find out where they were defined.
The MainPage class is a subclass of the Handler class. You don't show the definition of the Handler class but somewhere in your code you will find that it is a subclass of webapp2.RequestHandler.
To find what the two lines in your code are doing, you should go read the online documentation for webapp2.

Now I understand these two lines:
visits = self.request.cookies.get('visits','0')
self.request= requesting from the browser
self.request.cookies = requesting cookies[basically a dictionary] from the browser
self.request.cookies.get('visits')= looking for cookie whose key is visits
self.request.cookies.get("visits",0)= if key not found make this key value 0 and return
so now visits in LHS equals to 0 , as for now cookies not contain visits cookie
self.response.headers.add_header('Set-Cookie', 'visits=%s' %visits)
self.response= sending from the server to browser
self.response.headers.add_header('Set-Cookie', 'visits=%s' %visits)=adding cookie to header as it is defined in header, and setting visits in the cookie

Related

How I have to get data that store in database and uses in app of flask?

For example I have app on Flask with Postgresql. I have a some TOKENS and KEYS that stored in table companies. I need to get that tokens and keys in different places of my app. What the right way to do that? Any lazy approach?
Now I use app.config (but don't sure about app_context or before_first_request), for example:
with app.app_context():
if current_user:
app.config["CURRENT_COMPANY_ID"] = current_user.company_id
app.config["YANDEX_TOKEN"] =Company.query.filter_by(id=current_user.company_id).one().yandex_disk_token
or that:
with app.app_context():
if current_user:
g.company_id = current_user.company_id
g.yandex_token =Company.query.filter_by(id=current_user.company_id).one().yandex_disk_token
But that approaches sometimes lead to error that caused by current_user is None, or Company is None etc. And I can't recognize where and how I need store and get that TOKENS and KEY so all the users can use it after they are logged but not before that?
Find out:
It needs to update app.config constants before every user's request done. But if the current_user is not allowed (is None) then it will arise error so to make the current_user to not None we must use decorator #login_manager.request_loader
for example that code is placed in __init__ of app folder, and it solve two problems:
no empty current_user before every request we made to database via ORM.
no one request with empty app.config constants.
def set_config():
app.config['CURRENT_COMPANY_ID'] = current_user.company_id
app.config['YANDEX_TOKEN'] = Company.query.filter_by(id=current_user.company_id).first().yandex_disk_token
#login_manager.request_loader
def load_user_from_request(request):
user_id = request.headers.get('User-ID')
if user_id:
return UserModel.query.get(user_id)
return None
#app.before_request
def before_request():
if current_user.is_authenticated:
set_config()

How to get user information from database when the only thing in client browser is the AuthToken?

Building my first app with a real backend.
In my app, when a user registers or logs in (with username and password), a token is saved to the cookies of their browser. After registration (or when logging in), I can easily return information pertaining to this particular user (name, id, etc.).
# Django REST backend for loggin in and getting user token
class CustomAuthToken(ObtainAuthToken):
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(
data=request.data, context={'request': request})
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, created = Token.objects.get_or_create(user=user)
return Response({
'token': token.key,
'user_id': user.pk,
'email': user.email,
'user_type': user.user_type,
})
Next time the user accesses the app in the same device, the token will be there and I can make the http requests for which a token is necessary. However, since I won't be logging the user in again (not asking for username and password every single session), I won't get that user's additional information.
In my React app I would like to have the user set in state at all times, e.g. user = {first_name: 'john', user_type: 'p'} but I don't know how to get the user info when the only thing I have is their token.
I am more than welcome to criticism to this approach and to learning what's the best way of doing this. I don't even know if keeping the user in state is the right way to do things...
I tried this:
class UserAPI(generics.RetrieveUpdateAPIView):
serializer_class = UserSerializer
def get_object(self):
print(self.request.user)
return self.request.user
curl -H "Authorization: Token b2e33463esdf8as7d9f8j34lf98sd8a" http://localhost:8000/current-user/
but the return value from self.request.user is AnonymousUser
If it's not sensitive information, such as username, id, user type, first name, etc. you can store this in localStorage.
problem was in my settings.py file:
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
)
There are two parts of answer to this question. first part is criticism to your approach and little bit of guidance towards better approach, second part of the answer is about your actual question.
Lets start with second part first.
From the look of your code, you are already storing the key in Token Table along with User. You can easily get the user by first running this query token = Token.objects.get(key=key).select_related('user') and then simple user = token.user will give you token.
Coming to first part now.
Since you are using DRF, you do not need to override the class unless extremely necessary. If you want user with each approved request, what you can do is simply add your Token verification class to Settings of DRF
I had the same problem but I found how to do that this code will help you
if request.user.is_authenticated:
user = Account.objects.filter(username=request.user)
serializer = UserSerializer(user, many=True)
return Response(serializer.data)
else:
return Response('You have to login first')

how to test wagtail admin pages using the django test client?

I'm trying to write some tests using the Django Test Client to check on my customisations of the wagtail admin. I've tried:
self.user = get_user_model().objects.create(
username='addy', is_staff=True
)
self.client.force_login(self.user)
response = self.client.get(f'/admin/pages/{self.thing.id}/edit/')
But I still end up seeing an HttpResponseRedirect status_code=302, "text/html; charset=utf-8", url="/admin/login/?next=/admin/pages/6/edit/">
Am I missing some crucial attribute to the user that Wagtail wants in ordet to let them view wagtail-admin pages?
Wagtail doesn't use the is_staff flag to determine access to the admin - you need to assign your user the wagtailadmin.access_admin permission instead.
See https://github.com/wagtail/wagtail/blob/c6666c6de5e83bf94d18324858c121e6584ba47d/wagtail/wagtailsites/tests.py#L258 for an example of setting up a test user with the right permissions.
Here's what worked for me in the end:
self.user = get_user_model().objects.create_superuser(
username='addy', email='admin#example.com', password='passwood321'
)
Just setting is_staff wasn't enough. With due thanks to #gasman above, users don't have an is_admin atttribute. they do have is_superuser, so this code works just as well (and is probably better since it doesn't need an irrelevant email or password):
self.user = get_user_model().objects.create(username='addy', is_superuser=True)
self.client.force_login(self.user)

GAE - Retrieving Database content via commandline

I have the following GQL database model:
class Post(db.Model):
subject = db.StringProperty(required = True)
content = db.TextProperty(required = True)
created = db.DateTimeProperty(auto_now_add = True)
And this is the POST request used to store content to the database
def post(self):
subject = self.request.get('subject')
content = self.request.get('content')
if subject and content:
a = Post(subject = subject, content = content)
a.put()
self.redirect("/")
else:
error = "subject and content can neither be empty"
self.Render_NewPost(subject, content, error)
If I POST content to the database it works alright since i don't get the error. However I don't get the contents to show on the page it is suppose to show.
I'm interested in knowing the command line instruction I can use to check the database to be sure if the contents been posted are actually in the database or not so I can know where to figure out the problem of the content not showing on my Homepage as I hoped.
Thanks
Wait 30 seconds and refresh the page /. You may be running into the issue of "eventual consistency", where the data will "eventually" be put into the physical datastore you've queried, but may not be there yet.

Multiple calls to put() method when updating ndb on google app engine

I have a web app on GAE which uses a ndb database where each entity has as properties user informations and two string, the Entity class is like the one below
class UserPlus(ndb.Model):
user = ndb.UserProperty()
dogName = ndb.StringProperty(indexed=False)
catName = ndb.StringProperty(indexed=False)
The Main Page check if there's already an entity corresponding to that user, and if yes displays the value of the strings dogName and catName.
Then there's a form where users can update the values of dogName and catName . This performs a POST request to another page, the method below update the entiy
def post(self):
currentUser = users.get_current_user()
up = UserPlus.query(UserPlus.user==currentUser).get()
up.dogName = self.request.get('dog_name')
up.catName = self.request.get('cat_name')
weatherUser.put()
self.redirect('/')
But when I'm redirected to the Main Page, the values of dogName and catName are not updated until I refresh the page. I found that by calling the put() method two times instead of one, in the same position, this doesn't occur anymore, but I don't have clear why.
Am I doing something wrong or it's how ndb is supposed to work?
As Guido suspects and bossylobster/Fred Saur answered on my old question here - Should I expect stale results after redirect on local environment? - most likely eventual consistency problem.

Resources