Related
Here is an example of my form. How can I use python to modify the url and answer for the first question, as I am not familiar with using batchupdate?
I can use "get" to retrieve information from the form.
{'formId': '1q4pJMDtiLxQ2cjmLXxowqJ5VPfI68bUUo',
'info': {'title': 'PIXEL ', 'documentTitle': 'daily'},
'settings': {'quizSettings': {'isQuiz': True}},
'revisionId': '00000067',
'responderUri': 'https://docs.google.com/forms/d/e/1FAIpQLScap6ZdpOnWIyxWqZNXjlfWW9DgPe-Wv_CUtziWw/viewform',
'items': [{'itemId': '7c0ddb37', 'pageBreakItem': {}},
{'itemId': '2870b06c', 'videoItem': {'video': {'youtubeUri': 'www.youtube.com/watch?v=Lt5HqPvM-eI', 'properties': {'alignment': 'LEFT', 'width': 320}}}},
{'itemId': '381aedf6', 'questionGroupItem': {'questions': [{'questionId': '4d7f011e', 'required': True, 'rowQuestion': {'title': 'pick'}}], 'grid': {'columns': {'type': 'RADIO', 'options': [{'value': '1'}, {'value': '2'}, {'value': '3'}]}}}, 'title': 'pay'},
{'itemId': '0f9dc00b', 'title': 'number', 'questionItem': {'question': {'questionId': '39523976', 'required': True,
'grading': {'correctAnswers': {'answers': [{'value':'1115'}]}}, 'textQuestion': {}}}},
{'itemId': '0a12a42e', 'pageBreakItem': {}},
{'itemId': '19640fea', 'videoItem': {'video': {'youtubeUri': 'www.youtube.com/watch?v=Lt5HqPvM-eI', 'properties': {'alignment': 'LEFT', 'width': 320}}}},
{'itemId': '685ba545', 'questionGroupItem': {'questions': [{'questionId': '044f9f9b', 'required': True, 'rowQuestion': {'title': 'pick'}}], 'grid': {'columns': {'type': 'RADIO', 'options': [{'value': '1'}, {'value': '2'}, {'value': '3'}]}}}, 'title': 'pay'},
{'itemId': '6a9d1b88', 'title': 'number', 'questionItem': {'question': {'questionId': '2199beb0', 'required': True,
'grading': {'correctAnswers': {'answers': [{'value': '1115'}]}}, 'textQuestion': {}}}}]}
The official documentation has too few examples for me to understand how to apply it to my form.
update = {
"requests": [{
"updateItem": {
"item": {
"title": "Homework video",
"description": "Quizzes in Google Forms",
"videoItem": {
"video": {
"youtubeUri": "https://www.youtube.com/watch?v=Lt5HqPvM-eI"
}
}
},"location": {
"index": 0},
"updateMask": "description,youtubeUri"
}
}]
}
question_setting = service.forms().batchUpdate(
formId=form_id, body=update).execute()
From your following reply,
I want to update the youtubeUri item and use a new URL. How can I do this? i have two question use the video,how do i update the first question URL ?
I understood your question is as follows.
You want to update youtubeUri of 1st question in Google Forms using googleapis for python.
In this case, how about the following sample script?
Sample script:
service = # Please use your client
formId = "###" # Please set your Google Form ID.
after = "https://www.youtube.com/watch?v=###" # Please set YouTube URL you want to replace. In this sample, the existing URL is changed to this URL.
res = service.forms().get(formId=formId).execute()
itemIds = [[i, e["itemId"]] for i, e in enumerate(res.get("items")) if "videoItem" in e]
topItem = itemIds[0] # From your question, `youtubeUri` of the 1st question.
req = {
"requests": [
{
"updateItem": {
"item": {
"itemId": topItem[1],
"videoItem": {
"video": {
"youtubeUri": after,
}
},
},
"location": {"index": topItem[0]},
"updateMask": "videoItem.video.youtubeUri",
}
}
]
}
service.forms().batchUpdate(formId=formId, body=req).execute()
When this script is run, first, all items are retrieved. And, the item IDs including youtubeUri are retrieved. And, using the 1st item ID, the value of youtubeUri is changed to the value of after you set.
Note:
In this sample script, it supposes that you have already been able to get and out values to Google Form using Google Form API. Please be careful about this.
Reference:
Method: forms.batchUpdate
I'm manage to integrate SAML authentication in my Django application using the package Djangosaml2 and Pysaml2 with Azure as IdP provider.
everything is working properly I can login with SAML and log out.
What I don't understand is what is the use of having a metadata at the url https://panda.company.com/saml/metadata and what is the use of having a url https://panda.company.com/saml2/ls/ ?
Because with just the remote_metadata.xml provided by Azure is enough to login and logout.
SAML_CONFIG = {
'xmlsec_binary': '/usr/bin/xmlsec1',
'name': 'CloudBolt SP',
'entityid': 'https://panda.company.com/',
'service': {
'sp': {
'want_assertions_signed': False,
'want_response_signed': False,
'allow_unsolicited': True,
'endpoints': {
'assertion_consumer_service': [
('https://panda.company.com/saml2/acs/', saml2.BINDING_HTTP_POST),
],
'single_logout_service': [
('https://panda.company.com/saml2/ls/', saml2.BINDING_HTTP_REDIRECT),
],
},
'required_attributes': ['email'],
},
},
'debug': 1,
'key_file': os.path.join(SAML2_DIR, 'saml.key'), # private part
'cert_file': os.path.join(SAML2_DIR, 'saml.crt'), # public part
'allow_unknown_attributes': True,
'attribute_map_dir': os.path.join(/usr/local/lib/python3.6/site-packages/saml2/attributemaps'),
'metadata': {
'local': [os.path.join(SAML2_DIR, 'remote_metadata.xml')],
},
'contact_person': [{
'given_name': 'First',
'sur_name': 'Last',
'company': 'Company',
'email_address': 'me#company.com',
'contact_type': 'technical'
}],
'organization': {
'name': 'Company',
'display_name': 'Company',
'url': 'http://www.company.com',
},
'valid_for': 24, # how long is our metadata valid
'accepted_time_diff': 120, #seconds
}
SAML_DJANGO_USER_MAIN_ATTRIBUTE = 'username'
SAML_CREATE_UNKNOWN_USER = True
SAML_ATTRIBUTE_MAPPING = {
'email': ('email', ),
'givenName': ('first_name', ),
'sn': ('last_name', ),
'uid': ('username', ),
}
ENV: python 3.7+, boto3
I have list of private IP address ['10.0.3.11', '10.0.2.22']
response = route53_client.change_resource_record_sets(
HostedZoneId="ABDCEFGH",
ChangeBatch={
'Comment': 'Dns to ec2 instance',
'Changes': [
{
'Action': 'UPSERT',
'ResourceRecordSet': {
'Name': "ts-uat",
'Type': 'A',
'TTL': 120,
'ResourceRecords': [
{
'Value': record['Value']
},
]
}
}
]
}
)
How to get it as follows
HostedZoneId="ABDCEFGH",
ChangeBatch={
'Comment': 'Dns to ec2 instance',
'Changes': [
{
'Action': 'UPSERT',
'ResourceRecordSet': {
'Name': "ts-uat",
'Type': 'A',
'TTL': 120,
'ResourceRecords': [
{
'Value': 10.0.3.11
},
{
'Value': 10.0.2.22
},
]
}
}
]
}
)
I tried the following
def getListofIP(n):
return "{'value' : %s,}" % (n)
result = map(getListofIP, private_ip)
print(list(result))
output was
["{'value' : 10.0.3.11,}", "{'value' : 10.0.2.22,}"]
Thanks a lot #WillRichardson. it works for me
def getListofIP(n):
return {'Value' : '{}'.format(n)}
result = map(getListofIP, private_ip)
print(list(result))
Output
[{'Value': '10.0.3.11'}, {'Value': '10.0.2.22'}]
I want to retrieve max IOPS utilized by EBS volume in the last 2 weeks. I am using cloudwatch get_metric_data function to obtain data about metric VolumeReadOps and VolumeWriteOps. I am using following code to get VolumeReadOps and VolumeWriteOps and then trying to calculate MaxIOPS:
This is the function to get metric values:
def cloudwatch_metric_value(CWsession,NameSpace,ResourceIdentifier,vStat,vUnit,vMetricName,vPeriod):
"""
Function that returns metric value of cloudwatch for a given resource and metric Name
"""
if NameSpace=='EBS':
responseCW = CWsession.get_metric_data(
MetricDataQueries=[
{
'Id': 'string',
'MetricStat': {
'Metric': {
'Namespace': 'AWS/EBS',
'MetricName': vMetricName,
'Dimensions': [
{
'Name': 'VolumeId',
'Value': ResourceIdentifier
},
]
},
'Period': vPeriod,
'Stat': vStat,
'Unit': vUnit
},
'ReturnData': True
},
],
StartTime=vStartTime,
EndTime=vEndTime,
)
vValue=responseCW['MetricDataResults'][0]['Values']
vTimeStamps=responseCW['MetricDataResults'][0]['Timestamps']
index, value = max(enumerate(vValue), key=operator.itemgetter(1))
metric_value=value
metric_time=vTimeStamps[index]
return metric_time,metric_value
From main, it is called like following:
metric_time,metric_value = cloudwatch_metric_value(cloudwatch,'EBS',v['VolumeId'],'Sum','Count','VolumeReadOps',300)
vReadIOPS=metric_value
metric_time,metric_value = cloudwatch_metric_value(cloudwatch,'EBS',v['VolumeId'],'Sum','Count','VolumeWriteOps',300)
vWriteIOPS=metric_value
vTotalIOPS=round((vReadIOPS+vWriteIOPS)/300)
I understand that IOPS are calculated by diving the ReadOps/Write with duration. The values I get from this code for MaxIOPS for a given volume doesn't match with the values I see for same in cloudwatch console. Please advise if I am doing this in right way?
Thanks.
Ok, I was able to fix and here is the working function:
def cloudwatch_metric_value(CWsession,NameSpace,ResourceIdentifier,vStat,vUnit,vPeriod):
"""
Function that returns metric value of cloudwatch for a given resource and metric Name
"""
if NameSpace=='EBS':
responseCW = CWsession.get_metric_data(
MetricDataQueries=[
{
'Id': 'string1',
'MetricStat': {
'Metric': {
'Namespace': 'AWS/EBS',
'MetricName': 'VolumeReadOps',
'Dimensions': [
{
'Name': 'VolumeId',
'Value': ResourceIdentifier
},
]
},
'Period': vPeriod,
'Stat': vStat,
'Unit': vUnit
},
'ReturnData': True
},
{
'Id': 'string2',
'MetricStat': {
'Metric': {
'Namespace': 'AWS/EBS',
'MetricName': 'VolumeWriteOps',
'Dimensions': [
{
'Name': 'VolumeId',
'Value': ResourceIdentifier
},
]
},
'Period': vPeriod,
'Stat': vStat,
'Unit': vUnit
},
'ReturnData': True
},
],
StartTime=vStartTime,
EndTime=vEndTime,
)
vReadValue=responseCW['MetricDataResults'][0]['Values']
vReadTimeStamps=responseCW['MetricDataResults'][0]['Timestamps']
vWriteValue=responseCW['MetricDataResults'][1]['Values']
vWriteTimeStamps=responseCW['MetricDataResults'][1]['Timestamps']
vReadWriteValue = [vReadValue[i]+vWriteValue[i] for i in range(len(vWriteValue))]
if vReadWriteValue:
metric_value = max(vReadWriteValue)
metric_time = vReadTimeStamps[vReadWriteValue.index(metric_value)]
metric_value = metric_value / 300
else:
metric_value=1
metric_time=date_t
return metric_time,metric_value
I am grabbing sort of a complex MongoDB document with Python (v3.5) and I should update some values in it which are scattered all around the object and have no particular pattern in the structure and save it back to a different MongoDB collection. The object looks like this:
# after json.loads(mongo_db_document) my dict looks like this
notification = {
'_id': '570f934f45213b0d14b1256f',
'key': 'receipt',
'label': 'Delivery Receipt',
'version': '0.0.1',
'active': True,
'children': [
{
'key': 'started',
'label': 'Started',
'children': [
'date',
'time',
'offset'
]
},
{
'key': 'stop',
'label': 'Ended',
'children': [
'date',
'time',
'offset'
]
},
{
'label': '1. Particulars',
'template': 'formGroup',
'children': [
{
'children': [
{
'key': 'name',
'label': '2.1 Name',
'value': '********** THIS SHOULD BE UPDATED **********',
'readonly': 'true'
},
{
'key': 'ims_id',
'label': '2.2 IMS Number',
'value': '********** THIS SHOULD BE UPDATED **********',
'readonly': 'true'
}
]
},
{
'children': [
{
'key': 'type',
'readonly': '********** THIS SHOULD BE UPDATED **********',
'label': '2.3 Type',
'options': [
{
'label': 'Passenger',
'value': 'A37'
},
{
'label': 'Cargo',
'value': 'A35'
},
{
'label': 'Other',
'value': '********** THIS SHOULD BE UPDATED **********'
}
]
}
]
}
]
},
{
'template': 'formGroup',
'key': 'waste',
'label': '3. Waste',
'children': [
{
'label': 'Waste',
'children': [
{
'label': 'Plastics',
'key': 'A',
'inputType': 'number',
'inputAttributes': {
'min': 0
},
'value': '********** THIS SHOULD BE UPDATED **********'
},
{
'label': 'B. Oil',
'key': 'B',
'inputType': 'number',
'inputAttributes': {
'min': 0
},
'value': '********** THIS SHOULD BE UPDATED **********'
},
{
'label': 'C. Operational',
'key': 'C',
'inputType': 'number',
'inputAttributes': {
'min': 0
},
'value': '********** THIS SHOULD BE UPDATED **********'
}
]
}
]
},
{
'template': 'formRow',
'children': [
'empty',
'signature'
]
}
],
'filter': {
'timestamp_of_record': [
'date',
'time',
'offset'
]
}
}
My initial idea was to put placeholders (like $var_name) in places where I need to update values, and load the string with Python's string.Template, but that approach unfortunately breaks lots of stuff to other users of the same MongoDB document for some reason.
Is there a solution to simply modify this kind of object without "hardcoding" path to find the values I need to update?
There's this small script that I had written a couple years ago - I used it to find entries in some very long and unnerving JSONs. Admittedly it's not beautiful, but it might help in your case, perhaps?
You can find the script on Bitbucket, here (and here is the code).
Unfortunately it's not documented; at the time I wasn't really believing other people would use it, I guess.
Anyways, if you'd like to try it, save the script in your working directory and then use something like this:
from RecursiveSearch import Retriever
def alter_data(json_data, key, original, newval):
'''
Alter *all* values of said keys
'''
retr = Retriever(json_data)
for item_no, item in enumerate(retr.__track__(key)): # i.e. all 'value'
# Pick parent objects with a last element False in the __track__() result,
# indicating that `key` is either a dict key or a set element
if not item[-1]:
parent = retr.get_parent(key, item_no)
try:
if parent[key] == original:
parent[key] = newval
except TypeError:
# It's a set, this is not the key you're looking for
pass
if __name__ == '__main__':
alter_data(notification, key='value',
original = '********** THIS SHOULD BE UPDATED **********',
newval = '*UPDATED*')
Unfortunately as I said the script isn't well documented, so if you want to try it and need more info, I'll be glad to provide it.
Not sure if I understood correctly, but this will dynamically find all keys "value" and "readonly" and print out the paths to address the fields.
def findem(data, trail):
if isinstance(data, dict):
for k in data.keys():
if k in ('value', 'readonly'):
print("{}['{}']".format(trail, k))
else:
findem(data[k], "{}['{}']".format(trail, k))
elif isinstance(data, list):
for k in data:
findem(k, '{}[{}]'.format(trail, data.index(k)))
if __name__ == '__main__':
findem(notification, 'notification')
notification['children'][2]['children'][0]['children'][0]['readonly']
notification['children'][2]['children'][0]['children'][0]['value']
notification['children'][2]['children'][0]['children'][1]['readonly']
notification['children'][2]['children'][0]['children'][1]['value']
notification['children'][2]['children'][1]['children'][0]['readonly']
notification['children'][2]['children'][1]['children'][0]['options'][0]['value']
notification['children'][2]['children'][1]['children'][0]['options'][1]['value']
notification['children'][2]['children'][1]['children'][0]['options'][2]['value']
notification['children'][3]['children'][0]['children'][0]['value']
notification['children'][3]['children'][0]['children'][1]['value']
notification['children'][3]['children'][0]['children'][2]['value']
Add another list to the JSON object. Each item in that list would be a list of keys that lead to the values to be changed. An example for one such list is: ['children', 2, 'children', 'children', 0, 'value'].
Then, to access the value you could use a loop:
def change(json, path, newVal):
cur = json
for key in path[:-1]:
cur = cur[key]
cur[path[-1]] = newVal
path = notification['paths'][0]
#path, for example, could be ['children', 2, 'children', 'children', 0, 'value']
newVal = 'what ever you want'
change(notification, path, newVal)