Have the following scenario, in my JSON response there is a value called visit which can have either 1 or more than 1 element. So, if the visit have 1 element then the default payload should be sent next POST request or if the visit have more than 1 element then I'm fetching a random value and want to update the payload and sent to the next POST request.
Let me elaborate,
Condition 1 [Have 1 element in the visit section]
Condition 2 [Have more than 1 element in the visit section]
JSON Response for Condition 1
{"studyDTO":{"studyId":191,"studyCode":"test_ispptest2"},"sites":[{"studyId":191,"siteRecid":201,"siteId":"20000"}],"subjects":[{"studyId":191,"siteRecid":201,"subjectRecid":245,"subjectNumber":"20002"}],"states":null,"allVisits":true,"modalities":null,"examDates":null,"series":null,"transferType":null,"sftpLocations":[],"dicomLocations":[],"fileSystemLocations":[],"rawFileSystemLocations":[],"customFolder":null,"folderStructure":null,"customFile":null,"fileStructure":null,"includePS":null}
JSON Response for Condition 2
{"studyDTO":{"studyId":191,"studyCode":"test_ispptest2"},"sites":[{"studyId":191,"siteRecid":16521,"siteId":"11001"}],"subjects":[],"visits":[{"studyId":191,"visitSubmitName":"baseline","visitDisplayName":"Baseline","orderOfDisplay":10},{"studyId":191,"visitSubmitName":"cycle_1","visitDisplayName":"Cycle 1","orderOfDisplay":20}],"sftpLocations":[],"dicomLocations":[],"fileSystemLocations":[],"rawFileSystemLocations":[],"states":null,"modalities":null,"examDates":null,"series":null,"transferType":null,"customFolder":false,"customFile":false,"folderStructure":null,"fileStructure":null,"allSites":false,"allSubjects":true,"allVisits":false,"allStates":false,"allExamDates":false,"allModalities":false,"allSeries":false,"softEditOverride":false,"includePS":false,"includeSR":false,"includeRTStruct":false,"dicomTemplate":null,"errorMessage":null,"successMessage":null}
When I am in Condition 2, fetching random visitSubmitName,visitDisplayName,orderOfDisplay and updating in the payload.
Payload for condition 1:
{"studyDTO":{"studyId":191,"studyCode":"test_ispptest2"},"sites":[{"studyId":191,"siteRecid":201,"siteId":"20000"}],"subjects":[{"studyId":191,"siteRecid":201,"subjectRecid":245,"subjectNumber":"20002"}],"states":null,"allVisits":true,"modalities":null,"examDates":null,"series":null,"transferType":null,"sftpLocations":[],"dicomLocations":[],"fileSystemLocations":[],"rawFileSystemLocations":[],"customFolder":null,"folderStructure":null,"customFile":null,"fileStructure":null,"includePS":null}
Payload for condition 2:
{"studyDTO":{"studyId":191,"studyCode":"test_ispptest2"},"sites":[{"studyId":191,"siteRecid":16521,"siteId":"11001"}],"allSubjects":true,"states":null,"visits":[{"studyId":191,"visitSubmitName":"baseline","visitDisplayName":"Baseline","orderOfDisplay":10}],"modalities":null,"examDates":null,"series":null,"transferType":null,"sftpLocations":[],"dicomLocations":[],"fileSystemLocations":[],"rawFileSystemLocations":[],"customFolder":null,"folderStructure":null,"customFile":null,"fileStructure":null,"includePS":null}
Only change in the payload from condition 1 is,
Solution I have tried so far is created a JSR223 post processer with the following code:
import groovy.json.JsonSlurper
Random rnd = new Random();
def jsonString = prev.getResponseDataAsString();
def jsonConvert = new JsonSlurper();
def object = jsonConvert.parseText(jsonString);
def studyCode = object.studyDTO.studyCode;
def visitS = object.visits.size().toString();
def visitSize = visitS?.isInteger() ? visitS.toInteger() : null
def visitNUM = rnd.nextInt(visitSize);
//def defaultPayload = "{"studyDTO":{"studyId":${studyID},"studyCode":"${study_name}"},"sites":[{"studyId":${studyID},"siteRecid":${siteRecID},"siteId":"${siteID}"}],"subjects":[{"studyId":${studyID},"siteRecid":${siteRecID},"subjectRecid":${subjectRecID},"subjectNumber":"${subjectNumber}"}],"states":null,"allVisits":true,"modalities":null,"examDates":null,"series":null,"transferType":null,"sftpLocations":[],"dicomLocations":[],"fileSystemLocations":[],"rawFileSystemLocations":[],"customFolder":null,"folderStructure":null,"customFile":null,"fileStructure":null,"includePS":null}"
if (visitSize>1) {
def visitSubmitName = object.visits[visitNUM].visitSubmitName
def visitDisplayName = object.visits[visitNUM].visitDisplayName
def orderOfDisplay= object.visits[visitNUM].orderOfDisplay.toString();
//Change the payload with the three value
vars.put('payload',updatedPayload )
}
else {
vars.put('payload',defaultPayload )
}
And the next post sampler,
Error details:
Getting error with the defaultPayload declaration and need the logic for updating the payload.
Is the post sampler declared correctly?
Thanks, in advance
You either need to escape every quotation mark with a backslash
def defaultPayload = "def defaultPayload = '{\"studyDTO\":{\"studyId\":191,\"studyCode\":\"test_ispptest2\"},\"sites\":[{\"studyId\":191,\"siteRecid\":201,\"siteId\":\"20000\"}],\"subjects\":[{\"studyId\":191,\"siteRecid\":201,\"subjectRecid\":245,\"subjectNumber\":\"20002\"}],\"states\":null,\"allVisits\":true,\"modalities\":null,\"examDates\":null,\"series\":null,\"transferType\":null,\"sftpLocations\":[],\"dicomLocations\":[],\"fileSystemLocations\":[],\"rawFileSystemLocations\":[],\"customFolder\":null,\"folderStructure\":null,\"customFile\":null,\"fileStructure\":null,\"includePS\":null}'"
or use single quotation marks instead:
def defaultPayload = '{"studyDTO":{"studyId":191,"studyCode":"test_ispptest2"},"sites":[{"studyId":191,"siteRecid":201,"siteId":"20000"}],"subjects":[{"studyId":191,"siteRecid":201,"subjectRecid":245,"subjectNumber":"20002"}],"states":null,"allVisits":true,"modalities":null,"examDates":null,"series":null,"transferType":null,"sftpLocations":[],"dicomLocations":[],"fileSystemLocations":[],"rawFileSystemLocations":[],"customFolder":null,"folderStructure":null,"customFile":null,"fileStructure":null,"includePS":null}'
No, you either need to use just ${payload} or if you prefer coding go for __groovy() function like ${__groovy(vars.get('payload'),)}
More information:
Apache Groovy - Parsing and producing JSON
Apache Groovy: What Is Groovy Used For?
Guess Dmitri has solved your issue, now coming to the logic. Before that, if I checked your payload for the post request are different. Please try the below code in your JSR223 post-processer.
The json update could be done through json.builder
import groovy.json.JsonSlurper
import groovy.json.JsonBuilder
Random rnd = new Random();
def jsonString = prev.getResponseDataAsString();
def jsonConvert = new JsonSlurper();
def object = jsonConvert.parseText(jsonString);
def studyCode = object.studyDTO.studyCode;
def visitS = object.visits.size().toString();
def visitSize = visitS?.isInteger() ? visitS.toInteger() : null
def visitNUM = rnd.nextInt(visitSize);
def defaultPayload = '{"studyDTO":{"studyId":${studyID},"studyCode":"${study_name}"},"sites":[{"studyId":${studyID},"siteRecid":${siteRecID},"siteId":"${siteID}"}],"subjects":[{"studyId":${studyID},"siteRecid":${siteRecID},"subjectRecid":${subjectRecID},"subjectNumber":"${subjectNumber}"}],"states":null,"allVisits":true,"modalities":null,"examDates":null,"series":null,"transferType":null,"sftpLocations":[],"dicomLocations":[],"fileSystemLocations":[],"rawFileSystemLocations":[],"customFolder":null,"folderStructure":null,"customFile":null,"fileStructure":null,"includePS":null}';
def updatedPayLoad = "";
if (visitSize>1) {
def visitSubmitNameR = object.visits[visitNUM].visitSubmitName
def visitDisplayNameR = object.visits[visitNUM].visitDisplayName
def orderOfDisplayR = object.visits[visitNUM].orderOfDisplay.toString();
def newORDEROFDIS = orderOfDisplayR?.isInteger() ? orderOfDisplayR.toInteger() : null
updatedPayLoad = '{"studyDTO":{"studyId":${studyID},"studyCode":"${study_name}"},"sites":[{"studyId":${studyID},"siteRecid":${siteRecID},"siteId":"${siteID}"}],"allSubjects":true,"states":null,"visits":[{"studyId":${studyID},"visitSubmitName":"","visitDisplayName":"","orderOfDisplay":00}],"modalities":null,"examDates":null,"series":null,"transferType":null,"sftpLocations":[],"dicomLocations":[],"fileSystemLocations":[],"rawFileSystemLocations":[],"customFolder":null,"folderStructure":null,"customFile":null,"fileStructure":null,"includePS":null}'
def newUpdatedPayLoad = jsonConvert.parseText(updatedPayLoad);
def jsonBuilder = new JsonBuilder(newUpdatedPayLoad)
jsonBuilder.content.visits[0].visitSubmitName = visitSubmitNameR
jsonBuilder.content.visits[0].visitDisplayName = visitDisplayNameR
jsonBuilder.content.visits[0].orderOfDisplay = newORDEROFDIS
vars.put('finalPayLoad',jsonBuilder.toPrettyString())
}
else {
vars.put('finalPayLoad',defaultPayload)
}
I want to implement a search in Elastic Search with Django Rest Framework. I have a form for searching as follows.
I used a serializer to implement this form.
search.py:
class AdvancedSearch(mixins.ListModelMixin, viewsets.GenericViewSet):
serializer_class = AdvancedSearchSerializer
def query_builder(self, *args, **kwargs):
## building related query
return query
#get_db()
def get_queryset(self, db=None, *args, **kwargs):
serializer = self.get_serializer(data=self.request.data)
serializer.is_valid(raise_exception=True)
query = self.query_builder(search_input=serializer.validated_data)
response = db.search(query) # query the elastic with elasticsearch-dsl and return the results
if not response:
raise NoteFound()
return response
def list(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
self.serializer_class = AdvancedSearchSerializer
return super(AdvancedSearch, self).list(request, *args, **kwargs)
serializer.py:
class AdvancedSearchSerializer(serializers.Serializer):
metadata_choices = [('', ''), ...]
name = serializers.CharField(required=False, label='Name')
type = serializers.CharField(required=False, label='Type')
metadata = serializers.CharField(required=False, label='Metadata')
metadata_fields = serializers.MultipleChoiceField(allow_blank=True, choices=metadata_choices)
submit_date = serializers.DateTimeField(required=False)
def to_representation(self, instance):
output = {}
output['es_id'] = instance.meta.id
for attribute_name in instance:
attribute = getattr(instance, attribute_name)
if isinstance(attribute, (str, int, bool, float, type(None))):
# Primitive types can be passed through unmodified.
output[attribute_name] = attribute
elif isinstance(attribute, list):
# Recursively deal with items in lists.
output[attribute_name] = [
self.to_representation(item) for item in attribute
]
elif isinstance(attribute, (dict, AttrDict)):
temp = attribute.to_dict()
for key, value in temp.items():
print(key,value)
# Recursively deal with items in dictionaries.
output[attribute_name] = {
str(key): value
for key, value in temp.items()
}
else:
# Force anything else to its string representation.
output[attribute_name] = attribute
output['highlight'] = instance.meta.highlight.to_dict()
return [output]
With this code, I get the expected result, but I was wondering if this is a right approach.
And also in to_representation I have access to each result, but how can I add a total value like the number of results.
Thanks in advance.
Understand from many articles on stack overflow that the filter method in the tweepy.streaming.stream class uses a logical OR for track and location arguements
so the below will return either tweets from location=USA or with a word ""
streamObj = tweepy.streaming.Stream(oauthObject
,EchoStreamListener(api=apiInstance,
dump_json=args.json,
numtweets=args.numtweets))
keyWordList = ['panthers','falcon']
GEOBOX_USA = [-125,25.1,-60.5,49.1]
streamObj.filter(locations=GEOBOX_USA, track=keyWordList, languages=['en'])
This solution (How to add a location filter to tweepy module
) to check keywords in the on_status method works great, but if i needed to store the entire json variable i think i would have to use the on_data
so changed the on_data (as shown in code below), but get an error:
File "/Library/Python/2.7/site-packages/tweepy/streaming.py", line 294, in _run
raise exception
KeyError: 'text'
-- coding: utf-8 --
from types import *
import tweepy
import json
import argparse
import io
class EchoStreamListener(tweepy.StreamListener):
def __init__(self, api, dump_json=False, numtweets=0):
self.api = api
self.dump_json = dump_json
self.count = 0
self.limit = int(numtweets)
super(tweepy.StreamListener, self).__init__()
# def on_status(self, status):
# if any(keyWord in status.text.lower() for keyWord in keyWordList):
# print status.text
#
# self.count+=1
# return False if self.count == self.limit else True
# else:
# return True # Don't kill the stream
def on_data(self, tweet):
tweet_data = json.loads(tweet) # This allows the JSON data be used as a normal dictionary:
if any(keyWord in tweet_data['text'] for keyWord in keyWordList):
if self.dump_json:
print json.dumps(tweet_data)
saveFile.write(unicode(tweet) + "\n")
self.count+=1
return False if self.count == self.limit else True
else:
print tweet_data['created_at','name','text'].encode("utf-8").rstrip()
def on_error(self, status_code):
print >> sys.stderr, 'Encountered error with status code:', status_code
return True
def get_parser():
parser = argparse.ArgumentParser(add_help=True)
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument(
'-j', '--json',
action='store_true',
help='dump each tweet as a json string'
)
group.add_argument(
'-t', '--text',
dest='json',
action='store_false',
help='dump each tweet\'s text'
)
parser.add_argument(
'-n', '--numtweets',
metavar='numtweets',
help='set number of tweets to retrieve'
)
return parser
if __name__ == '__main__':
oauthObject = tweepy.OAuthHandler(myconsumer_key, myconsumer_secret)
oauthObject.set_access_token(myaccess_key,myaccess_secret)
apiInstance = tweepy.API(oauthObject)
parser = get_parser()
args = parser.parse_args()
streamObj = tweepy.streaming.Stream(oauthObject
,EchoStreamListener(api=apiInstance,
dump_json=args.json,
numtweets=args.numtweets))
keyWordList = ['panthers','falcon']
GEOBOX_USA = [-125,25.1,-60.5,49.1]
saveFile = io.open('/Users/deepaktanna/raw_tweets.json', 'w', encoding='utf-8')
streamObj.filter(locations=GEOBOX_USA, languages=['en'])
saveFile.close()
My View :
def refer(request, seek_id):
seek_obj = SeekSolutions.objects.get(pk = seek_id)
if request.method == 'POST':
form = SeekReferForm(request.POST)
if form.is_valid():
obj = form.save(commit = False)
obj.refferer = request.user
obj.seek_id = seek_obj
obj.save()
send_message(obj)
return HttpResponseRedirect('/seek/referred')
return render_to_response('seek/refer.html', {'form' : form , } )
Traceback :
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/handlers/base.py in get_response
response = callback(request, *callback_args, **callback_kwargs) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/contrib/admin/options.py in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/decorators.py in _wrapped_view
response = view_func(request, *args, **kwargs) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/views/decorators/cache.py in _wrapped_view_func
response = view_func(request, *args, **kwargs) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/contrib/admin/sites.py in inner
return view(request, *args, **kwargs) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/decorators.py in _wrapper
return bound_func(*args, **kwargs) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/decorators.py in _wrapped_view
response = view_func(request, *args, **kwargs) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/decorators.py in bound_func
return func(self, *args2, **kwargs2) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/contrib/admin/options.py in changelist_view
'selection_note': _('0 of %(cnt)s selected') % {'cnt': len(cl.result_list)}, ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/query.py in __len__
self._result_cache = list(self.iterator()) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/query.py in iterator
for row in compiler.results_iter(): ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/sql/compiler.py in results_iter
for rows in self.execute_sql(MULTI): ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/sql/compiler.py in execute_sql
cursor.execute(sql, params) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/backends/util.py in execute
return self.cursor.execute(sql, params) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py in execute
return Database.Cursor.execute(self, query, params) ...
▶ Local vars
Although this question is pretty old, since I ran in to the same problem(and just solved it) I think I ought to answer to it for future references. But then I had a different error. But you seem to be missing something in your code.
def refer(request, seek_id):
seek_obj = SeekSolutions.objects.get(pk = seek_id)
if request.method == 'POST':
form = SeekReferForm(request.POST)
if form.is_valid():
obj = form.save(commit = False)
obj.refferer = request.user
obj.seek_id = seek_obj
obj.save()
send_message(obj)
return HttpResponseRedirect('/seek/referred')
else:
form = SeekReferForm()
return render_to_response('seek/refer.html', {'form' : form , } )
This includes an else block to your first if. This is because when you try to access the url from your browser, you are essentially doing a GET request on the resource. As a result the first if is violated and comes directly to the return statement where it tries to return a dictionary item with 'form' as the key and a form object which was never created at all. Thus the error in your code. There need to be an else part which is supposed to instantiate the form object in case you try to open the url in your browser. I hope that helps the cause.
the form is instantiated only when request.method == 'POST'.
this is my form:
class IPTrackerSearchForm(forms.Form):
keyword = forms.CharField(max_length=100, widget=forms.TextInput(attrs={'size':'50'}))
search_in = forms.ChoiceField(required=False, choices=ANY_CHOICE + MODULE_SEARCH_IN_CHOICES)
product = forms.CharField(max_length=64,widget=forms.TextInput(attrs={'size':'50'}))
family = forms.CharField(max_length=64,widget=forms.TextInput(attrs={'size':'50'}))
temp_result = Merlin.objects.values('build').distinct()
result = [(value['build'], value['build']) for value in temp_result]
build = forms.ChoiceField(choices=ANY_CHOICE + result)
circuit_name = forms.CharField(max_length=256,widget=forms.TextInput(attrs={'size':'50'}))
parameterization = forms.CharField(max_length=1024,widget=forms.TextInput(attrs={'size':'50'}))
metric = forms.CharField(max_length=64,widget=forms.TextInput(attrs={'size':'50'}))
show_in_one_page = forms.BooleanField(required=False, label="Show filtered result in one page", widget=forms.CheckboxInput(attrs={'class':'checkbox'}))
def __init__(self, *args, **kwargs):
super(IPTrackerSearchForm, self).__init__(*args, **kwargs)
temp_result = Merlin.objects.values('build').distinct()
self.result = [(value['build'], value['build']) for value in temp_result]
self.build = forms.ChoiceField(choices=ANY_CHOICE + self.result)
print self.result
With the purpose that, each time I refresh the webpage, when have new record to "build" column in database. It should update to the drop down box "build" here but It never update unless restart the server. I use print and see that __init__ detect new record but can not refect to build in Class.
Many thanks
You actually need to update self.fields['build'] instead of self.build.
def __init__(self, *args, **kwargs):
super(IPTrackerSearchForm, self).__init__(*args, **kwargs)
temp_result = Merlin.objects.values('build').distinct()
result = [(value['build'], value['build']) for value in temp_result]
self.fields['build'] = forms.ChoiceField(choices=ANY_CHOICE + result)
print result
Because you're not updating self.fields, you are seeing the result of the query at compile time, not execution.