gae-sessions 'thread._local' object has no attribute 'current_session' - python

I'm trying to get gae-sessions working, but am having an issue.
I've logged inside of appengine_config.py and inside of webapp_add_wsgi_middleware and it is being called.
I've logged inside the libs __init__.py and it's running __init__, __call__ and my_start_response inside SessionMiddleware without issue.
My problem is that the second I try to actually use the session with:
session = get_current_session()
I get this:
session = get_current_session()
File "gaesessions\__init__.py", line 38, in get_current_session
return _tls.current_session
AttributeError: 'thread._local' object has no attribute 'current_session'

Well the problem seems to be that I can only call get_current_session within a get request handler. If I try to call a function in another module from the get request handler, that itself requests the session, I get the above error.

Related

serverless starting error: ModuleNotFoundError: No module named 'handler' [duplicate]

I have a deployment package in the following structure:
my-project.zip
--- my-project.py
------ lambda_handler()
Then I define the handler path in configuration file
my-project.lambda_handler
Get the error:
'handler' missing on module
Can not understand that
There are some issues occurring this error.
Issue#1:
The very first issue you’re gonna run into is if you name the file incorrectly, you get this error:
Unable to import module 'lambda_function': No module named lambda_function
If you name the function incorrectly you get this error:
Handler 'handler' missing on module 'lambda_function_file': 'module'
object has no attribute 'handler'
On the dashboard, make sure the handler field is entered as function_filename.actual_function_name and make sure they match up in your deployment package.
If only the messages were a bit more instructive that would have been a simpler step.
Resource Link:
No lambda_function?
Issue#2:
adrian_praja has solved the issue in aws forum. He answered the following
I belive your index.js should contain
exports.createThumbnailHandler = function(event, context) {}
Issue#3:
Solution: Correctly specify the method call
This happens when the specification of the method called by node.js is incorrect in Lambda's setting.
Please review the specification of the method to call.
In the case of the above error message, I attempted to call the handler method of index.js, but the corresponding method could not be found.
The processing to call is set with "Handler" on the configuration tab.
Below is an example of setting to call the handler method of index.js.
Resource Link:
http://qiita.com/kazuqqfp/items/ac8d93918d0030b31aad
AWS Lambda Function is returning Handler 'handler' missing on module 'index'
I had this issue and had to make sure I had a function called handler in my file, e.g.:
# this just takes whatever is sent to the api gateway and sends it back
def handler(event, context):
try:
return response(event, 200)
except Exception as e:
return response('Error' + e.message, 400)
def response(message, status_code):
return message

Python Flask App Error: 'function' object has no attribute 'get' using Flask-Dance

I'm using Flask-Dance for letting the user to login with google. But when I go to the route below it tells me: 'function' object has no attribute 'get'.
What do I do wrong?
If I write "if not google.authorized" it raises an error too.
from flask_dance.contrib.google import make_google_blueprint, google
app.register_blueprint(google_blueprint, url_prefix='/login')
google_blueprint = make_google_blueprint(client_id='client_id', client_secret='client_secret')
#app.route('/google')
def google():
if not google_blueprint.authorized:
return redirect(url_for('google.login'))
account_info = google.get("/plus/v1/people/me")
assert account_info.ok, account_info.text
return "You are {email} on Google".format(email=resp.json()["emails"][0]["value"])
You import google in line 1, but later on line 7 you define a function google which overrides the object from import and essentially hides it, so the line account_info = google.get("/plus/v1/people/me") is trying to call get on your function instead of the google module you imported.
Rename your function to something else, like google_endpoint and it will work.
Change the name of a function
from flask_dance.contrib.google import make_google_blueprint, google
def google():

Flask cache set method throwing KeyError?

In order to cache some data, I am calling cache.set method. However it is throwing KeyError. The error log:
File "D:\Sample_Project\SomeRouter.py", line 176, in run
FetchFeed._prepareCache(f_content, cache, _program, _sprint)
File "D:\Sample_Project\SomeRouter.py", line 197, in _prepareCache
cache.set(cKey, data[last_index:last_index + MAX_DATA_PER_PAGE])
File "c:\python\lib\site-packages\flask_caching\__init__.py", line 254, in set
return self.cache.set(*args, **kwargs)
File "c:\python\lib\site-packages\flask_caching\__init__.py", line 246, in cache
return app.extensions["cache"][self]
KeyError: <flask_caching.Cache object at 0x04F9C8D0>
The server module looks like :
cache_type = 'simple' if 'FLASK_ENV' in os.environ and os.environ['FLASK_ENV'] == 'development' else 'uwsgi'
cache = Cache(config={'CACHE_TYPE': cache_type})
app = Flask("MY_PROJECT")
cache.init_app(app)
# some api.route functions
# goes here ....
if __name__ == "__main__":
with app.app_context():
cache.clear()
app.run(host="0.0.0.0")
And SomeRouter module:
from server import cache
#staticmethod
def _prepareCache(data, cache, program):
total_records = len(data)
if total_records > 0:
cKey = FetchFeed \
._constructCacheKey(program)
cache.set(cKey, data)
else:
print("data size is empty.")
Note: I have removed unnecessary codes.
I also put breakpoints, and called cache.set(some_key, some_value) in server module itself. It is returning True, but same cache object is throwing KeyError when imported and used in SomeRouter module. Can it be that the way I am importing an object is wrong? I also tried importing the cache object right before using it, but it did not work. Any idea what is going on here?
The problem was I was accessing cache object outside request context i.e. in "SomeRouter" module, and because of which it was unaware that under which context it is been used.
In server module where request has been received, the cache knows about the app application, but during cache.set(cKey, data) in SomeRouter module, it throws KeyError. This error is justified as mentioned above.
The resolution is to push the application context as below:
from server import app, cache
# Using context
with app.app_context():
cache.set(cKey, data)
This will push a new application context (using the application of app).
All thanks to Mark Hildreth, for his great answer on context in flask

TypeError: 'str' object is not callable Flask Redirect

I can't get Flask to redirect!
I keep getting a
File "/Users/kyle.calica-steinhil/Code/wcp2018/wcp18/app/app.py", line 32, in slackRedirect
return redirect(url)
TypeError: 'str' object is not callable
I have no idea why this is not working. I'm passing a string in redirect() I'm pretty sure that's what it takes.
I've also tried ' to "
Code:
slackAPI='https://slack.com/oauth/authorize'
slack_client_id='XXXXXXXXXXXXXXXX'
scope='bot'
redirect='http://localhost:5000/'
#app.route('/auth')
def slackRedirect():
url = slackAPI+'?client_id='+slack_client_id+'&scope='+scope+'&redirect_uri='+redirect
return redirect(url)
You are redefining what redirect means. redirect redirects client to target location, so just rename redirect to something else, following line:
redirect_url='http://localhost:5000/'
The problem you are facing is with naming conflicts. Your module level variable redirect actually overrides the flask.redirect() method that you are trying to use:
redirect='http://localhost:5000/'
Rename this redirect variable to something else and your problem will be solved. That's assuming you've properly imported the flask.redirect method in your module:
from flask import redirect

DetachedInstanceError when creating Pyramid Session with SQLAlchemy

I wrote my own implementation of the ISession interface of Pyramid which should store the Session in a database. Everything works real nice, but somehow pyramid_tm throws up on this. As soon as it is activated it says this:
DetachedInstanceError: Instance <Session at 0x38036d0> is not bound to a Session;
attribute refresh operation cannot proceed
(Don't get confused here: The <Session ...> is the class name for the model, the "... to a Session" most likely refers to SQLAlchemy's Session (which I call DBSession to avoid confusion).
I have looked through mailing lists and SO and it seems anytime someone has the problem, they are
spawning a new thread or
manually call transaction.commit()
I do neither of those things. However, the specialty here is, that my session gets passed around by Pyramid a lot. First I do DBSession.add(session) and then return session. I can afterwards work with the session, flash new messages etc.
However, it seems once the request finishes, I get this exception. Here is the full traceback:
Traceback (most recent call last):
File "/home/javex/data/Arbeit/libraries/python/web_projects/pyramid/lib/python2.7/site-packages/waitress-0.8.1-py2.7.egg/waitress/channel.py", line 329, in service
task.service()
File "/home/javex/data/Arbeit/libraries/python/web_projects/pyramid/lib/python2.7/site-packages/waitress-0.8.1-py2.7.egg/waitress/task.py", line 173, in service
self.execute()
File "/home/javex/data/Arbeit/libraries/python/web_projects/pyramid/lib/python2.7/site-packages/waitress-0.8.1-py2.7.egg/waitress/task.py", line 380, in execute
app_iter = self.channel.server.application(env, start_response)
File "/home/javex/data/Arbeit/libraries/python/web_projects/pyramid/lib/python2.7/site-packages/pyramid/router.py", line 251, in __call__
response = self.invoke_subrequest(request, use_tweens=True)
File "/home/javex/data/Arbeit/libraries/python/web_projects/pyramid/lib/python2.7/site-packages/pyramid/router.py", line 231, in invoke_subrequest
request._process_response_callbacks(response)
File "/home/javex/data/Arbeit/libraries/python/web_projects/pyramid/lib/python2.7/site-packages/pyramid/request.py", line 243, in _process_response_callbacks
callback(self, response)
File "/home/javex/data/Arbeit/libraries/python/web_projects/pyramid/miniblog/miniblog/models.py", line 218, in _set_cookie
print("Setting cookie %s with value %s for session with id %s" % (self._cookie_name, self._cookie, self.id))
File "build/bdist.linux-x86_64/egg/sqlalchemy/orm/attributes.py", line 168, in __get__
return self.impl.get(instance_state(instance),dict_)
File "build/bdist.linux-x86_64/egg/sqlalchemy/orm/attributes.py", line 451, in get
value = callable_(passive)
File "build/bdist.linux-x86_64/egg/sqlalchemy/orm/state.py", line 285, in __call__
self.manager.deferred_scalar_loader(self, toload)
File "build/bdist.linux-x86_64/egg/sqlalchemy/orm/mapper.py", line 1668, in _load_scalar_attributes
(state_str(state)))
DetachedInstanceError: Instance <Session at 0x7f4a1c04e710> is not bound to a Session; attribute refresh operation cannot proceed
For this case, I deactivated the debug toolbar. The error gets thrown from there once I activate it. It seems the problem here is accessing the object at any point.
I realize I could try to detach it somehow, but this doesn't seem like the right way as the element couldn't be modified without explicitly adding it to a session again.
So when I don't spawn new threads and I don't explicitly call commit, I guess the transaction is committing before the request is fully gone and afterwards there is again access to it. How do I handle this problem?
I believe what you're seeing here is a quirk to the fact that response callbacks and finished callbacks are actually executed after tweens. They are positioned just between your app's egress, and middleware. pyramid_tm, being a tween, is committing the transaction before your response callback executes - causing the error upon later access.
Getting the order of these things correct is difficult. A possibility off the top of my head is to register your own tween under pyramid_tm that performs a flush on the session, grabs the id, and sets the cookie on the response.
I sympathize with this issue, as anything that happens after the transaction has been committed is a real gray area in Pyramid where it's not always clear that the session should not be touched. I'll make a note to continue thinking about how to improve this workflow for Pyramid in the future.
I first tried with registering a tween and it worked somehow, but the data did not get saved. I then stumpled upon the SQLAlchemy Event System. I found the after_commit event. Using this, I could set up the detaching of the session object after the commit was done by pyramid_tm. I think this provides the full fexibility and doesn't impose any requirements on the order.
My final solution:
from sqlalchemy.event import listen
from sqlalchemy.orm import Session as SASession
def detach(db_session):
from pyramid.threadlocal import get_current_request
request = get_current_request()
log.debug("Expunging (detaching) session for DBSession")
db_session.expunge(request.session)
listen(SASession, 'after_commit', detach)
Only drawback: It requires calling get_current_request() which is discouraged. However, I saw no way of passing the session in any way, as the event gets called by SQLAlchemy. I thought of some ugly wrapping stuff but I think that would have been way to risky and unstable.

Categories