Configure WebApp2 request and response. Create and close session objects along them - sqlalchemy

I am creating a webapp2, SQLalchemy, postgresql based web application.
My question is: *How to create the SQLAlchemy session object (scoped_session) whenever a request comes and close the same object while sending the response.*
Going through the docs I understood that this is the best possible method of creating and closing the session object. But how to achieve it with WebApp2 I am not sure. If someone knows a better and efficient way of doing it then please let me know.
Currently I am creating a scoped_session obj in a config file and I import this file and use the obj wherever needed. I have not closed the object anywhere which I guess is not a good practice. What I want to achieve is whenever there is a request from browser, I get a new session object, use this session object to interact with database and when response is returned close the session object.
Thanks

Overriding dispatch() seems to be the way to go:
class MyHandler(webapp2.RequestHandler):
def dispatch(self):
try:
ret = webapp2.RequestHandler.dispatch(self)
Session().commit()
return ret
except:
Session().rollback()
raise
This assume that you have something like this: Session = scoped_session(sessionmaker()) so Session() always returns the threadlocal session.
Note: I don't know webapp2 and so I am not sure if this is exactly the right place. For example, I'm not sure if there may be an exception handler in the dispatch call of the parent class. So you might need a similar technique on a different place (or another way to detect an error here).

Related

JSON serialisers and alternative http responses with Django

I'm trying to create a filter system on a click event - using an AJAX post method to update the context that is shown on the template.
I'm currently using:
return HttpResponse(json.dumps(context), content_type="application/json")
To return a response with a context object. However, this doesn't quite work with certain object types:
TypeError: is not JSON serializable
I know there's something regarding serialisers but I'm currently unable to either a.) use them correctly or b.) use them at all.
For some context I'm passing filter variables to the view with the AJAX post method - then:
posts = Post.published.filter(category__name__in=category_filter_items)
And adding this to my context:
context['posts'] = posts
Would anyone know the correct way to update the context is such a manner?
First of all, you should know that once the Django template is rendered, you can't dynamically modify its context without rendering it again. See template documentation.
Before modifying dynamically your template, you should really consider a way to filter your data by calling a view that renders the template again with the context you need.
Option 1: Render the template again
def my_view(request):
posts = Posts.objects.all()
# TODO: Filter the posts against the request
template = loader.get_template('template.html')
context = {
'posts': posts,
}
return HttpResponse(template.render(context, request))
Option 2: Modify your template dynamically
If you're sure that modifying your template dynamically is your best / only choice, you've got different ways to achieve this.
One of them is changing your template via jQuery, loading a subtemplate that is rendered by your filtering view. Take a look at this issue.
Another way is to get your filtered data via a JSON Api and make sure your template is updated accordingly. You may want to use Angular for instance, which uses a MVVM architecture pattern.
How to serialize models in Django?
Django provides serialization of models as a core feature.
Serializing your models to JSON is as simple as:
from django.core.serializers import serialize
serialize('json', SomeModel.objects.all())
If you need to implement an API with serialization of models AND filtering, you may want to use django-rest-framework.
What about use JsonResponse instead of HttpResponse? also you need to define a serializer for Post model.

Swift - Store JSON globally

i have this JSON array stored in my local variable:
let bigJsonArray = JSON(response)
my question is if there is any possibility to store this "bigJsonArray" in a global variable/session/cookie/config so i can access it in every view of my app ?
Anybody knows how to process this and could help me?
Greetings and thanks!
What you can do is to define bigJsonArray as a global variable just by defining it outside of any class and the Swift compiler will understand it as a global variable and you can access it from anywhere in your code.
for example:
import UIKit
var bigJsonArray = JSON(response)
class a {
var x = 0
}
that's of curse will not save the data if you killed the app, but from what I understand from your question you just need to be able to access it from all the app without resending a request to the server.
If you want to save the JSON data permanently, you just store the data that you received as a file, and the next time you need it, you read it from the file and parse it (there's actually a method for that) instead of downloading and parsing the data. Much easier than trying to store the parsed data.
If this is data that can be downloaded again, read the appropriate documentation to make sure the file isn't backed up, and is stored in a cache directory where the OS can remove it if space is tight.

Why do I get loose closing brackets for my Django Rest Framework endpoint?

Here's my JSON response for http://localhost:8000/characters/api/users/1?format=json
)]}',
{"id":1,"username":"admin","mage_by_user":[3],"mage_last_updated":"2015-02-11T16:13:16.229Z"}
Notice the )]}', on the first line.
Here is my code that gets called to create the JSON:
class UserSerializer(serializers.ModelSerializer):
mage_by_user = serializers.PrimaryKeyRelatedField(
many=True, queryset=Mage.objects.all())
mage_last_updated = serializers.ReadOnlyField(
source='mage_by_user.updated_date')
class Meta:
model = User
fields = ('id', 'username', 'mage_by_user', 'mage_last_updated',)
Further testing:
I've noticed the title of the page is TypeError at <insert url here>.
This happens with all of my endpoints
If I try to access a non-existent object (userId=2 for instance), then renders 'normally' for DRF, e.g:
{
detail: "Not found"
}
Any idea why this would happen?
Those characters are inserted by the Djangular middleware AngularJsonVulnerabilityMiddleware, to inject Json Vulnerability Protection
A JSON vulnerability allows third party website to turn your JSON resource URL into JSONP request under some conditions. To counter this your server can prefix all JSON requests with following string ")]}',\n". Angular will automatically strip the prefix before processing it as JSON.
Unfortunately, it means it breaks various JSON viewers.
Sorry to not be more help, but this looks like something entirely unrelated to REST framework. There's absolutely no way a JSON response there would ever be rendered in that way.
Perhaps you have a custom renderer configured, that's outputting a malformed response, perhaps you have some broken middleware inserting those characters, perhaps its an issue in the client or whatever environment you're making the requests, or perhaps it's something else entirely unrelated to any of those.
I'd start by trying to narrow down the issue as much as possible - remove all the complexity from the view and serializer and attempt to replicate the behavior in a test case.
Most likely there's some sort of unexpected integration issue you're missing or some otherwise obvious code typo that's being overlooked.

JBPM rest calls with JSON

We want to start a process in JBPM6 using the rest API. We need to pass an object as a process variable.
We know how to do it JAXB and the execute call. But we want to do it with JSON and /runtime/{deploymentId}/process/{processDefId}/start
Is it possible? we try and have no success.
I am not sure whether my answer exactly addresses the question. But for someones use in future I place couple of lines here.
If you want to set a process variable when starting a process using the RESTful API, you can do it like this.
If your variable name is myVar just add the value as a URL parameter by appending the phrase "map_" to the parameter name. It means the parameter name should now be map_myVar. For an example see below request.
http://<host>:<port>/jbpm-console/rest/runtime/{deploymentId}/process/{processDefId}/start?map_myVar=myValue
You can confirm whether the value is set by writing below code in a script task.
Object var = kcontext.getVariable("myVar");
System.out.println("myVar : " + var);
See the 17.1.1.3. Map query parameters section of JBPM6 documentation.
After talking to the dev that is responsible for the REST API. I was able to confirm how it works.
The
/runtime/{deploymentId}/process/{processDefId}/start
Is a POST request where all the contents in the payload are ignored. The variables are written as key=value in the GET string.
With deployment id: com.web:work:1.0
With processDefId: work.worload
2 variables: var1 and var2
For example:
/runtime/com.web:work:1.0/process/work.worload/start?var1=a&var2=b
I'm still after trying to understand how to define objects with the remote API.
Meanwhile, I also confirmed that it is impossible to define objects using this way. The only way to define objects is only by using the JaxB. This uses the "/execute" path

How can I enable GZIP compression of the JSON response entity on Reslet?

I have a Restlet application already working that accepts JSON and returns JSON entity as response.
I'm trying to understand how I can compress the JSON entity that is returned in the response.
I did not find any clear example on how to achieve it.
I think I have to put somewhere on the router chain the Encoder/EncoderService classes, but I really don't understand where and how to use them.
Could anybody help me?
After some testing, I got the answer.
Creating a new filter like this
Filter encoder = new Encoder(getContext(), false, true, new EncoderService(true));
inside the createInboundRoot() method of my own Application class did the trick, the client requests were already containing the gzip header needed.