Process JSON Responses, Editing and Sending - python

I am working with an API. I get a response from the API which looks like this:
from oauthlib.oauth2 import BackendApplicationClient
from requests.auth import HTTPBasicAuth
from requests_oauthlib import OAuth2Session
auth = HTTPBasicAuth(client_id, client_secret)
client = BackendApplicationClient(client_id=client_id)
oauth = OAuth2Session(client=client)
token = oauth.fetch_token(token_url=token_url, auth=auth)
client = OAuth2Session(client_id, token=token, auto_refresh_url=token_url,token_updater=token_saver)
token_saver = []
device_policy = client.get('{URL}/v1?ids='+ids)
I get this response
[{'id': '',
'name': 'A Name',
'description': '',
'platform_name': 'Windows',
'groups': [],
'enabled': True,
'created_by': 'An Email',
'created_timestamp': '2019-03-28T12:51:30.989736386Z',
'modified_by': 'An Email ,
'modified_timestamp': '2019-11-19T21:14:53.0189419Z',
'settings': {'enforcement_mode': 'MONITOR_ENFORCE',
'end_user_notification': 'SILENT',
'classes': [{'id': 'ANY', 'action': 'FULL_ACCESS', 'exceptions': []},
{'id': 'IMAGING', 'action': 'FULL_ACCESS', 'exceptions': []},
{'id': 'MASS_STORAGE', 'action': 'BLOCK_ALL', 'exceptions': []},
{'id': 'MOBILE', 'action': 'BLOCK_ALL', 'exceptions': []},
{'id': 'PRINTER', 'action': 'FULL_ACCESS', 'exceptions': []},
{'id': 'WIRELESS', 'action': 'BLOCK_ALL', 'exceptions': []}]}}]
In each class there is list for hold exceptions. The API accepts a patch (not really a patch) that if this data is resubmitted with the exception field holding the contents of this function then an exception is accepted.
`
file_info = {
"class": "ANY",
"vendor_name": "",
"product_name": "",
"serial_number": serial_number,
"combined_id": "",
"action": "FULL_ACCESS",
"match_method": "VID_PID_SERIAL"
}
`
The challenge I have is accepting the first document and then adding the exception material to create a this patch request. I can "walk" the document but cannot work how to create a new body text to send. I think I want to do something like this but not using append as this throws an error.
new_walk_json = walk_json.append(['classes'][0]['exceptions']['Test'])

Realised .update function can used.

Related

How can I use the batchupdate function of the google form api with python to modify the url and answers?

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

python - aiohttp.ClientSession().post

So, I had this code and it worked perfectly fine:
def upload_to_imgur(url):
j1 = requests.post(
"https://api.imgur.com/3/upload.json",
headers=headers,
data={
'key': api_key,
'image': b64encode(requests.get(url).content),
'type': 'base64',
'name': '1.jpg',
'title': 'Picture no. 1'
}
)
data = json.loads(j1.text)['data']
return data['link']
Now, I wanted to make all this async, but that doesn't really seem to work. Here's my current code:
async def async_upload_to_imgur(url):
image = await get_as_base64(url)
j1 = await aiohttp.ClientSession().post(
"https://api.imgur.com/3/upload.json",
headers=headers,
data={
'key': api_key,
'image': image,
'type': 'base64',
'name': '1.jpg',
'title': 'Picture no. 1'
}
)
data = await j1.json()
return data['link']
The get_as_base64-function is not the issue.
Header and Api Key are the same
This is the output when I print "data" in the second example.
{'data': {'error': {'code': 1001, 'message': 'File was not uploaded correctly', 'type': 'Exception_Logged', 'exception': {}}, 'request': '/3/upload.json', 'method': 'POST'}, 'success': False, 'status': 500}
It has to be the get_as_base64, for 2 reasons -:
1.) It says the file was not uploaded correctly meaning it doesn't support the URL or something like that
2.) I think you need to link a file not a link containing the file in it.

Parse JSON value into key-value attributes

I got the following output from my API:
{
'Type': 'Notification',
'MessageId': 'xxx',
'TopicArn': 'xxx',
'Subject': 'xxx',
'Message': 'EventType=Delete, FriendlyType=was deleted, '
'Timestamp=2021-11-08T15:30:45Z, UserId=1111, UserName=me#me.com, '
'IPAddr=(empty), AccountId=22222, AccountName=test-account, '
'ProjectId=test-project',
'Timestamp': '2021-11-08T15:30:46.214Z',
'SignatureVersion': '1'
}
Now I want to access the "Message" variable - once I am in, and get the following output (as already visible in the previous mentioned JSON):
EventType=Delete, FriendlyType=was deleted, Timestamp=2021-11-08T15:30:45Z, UserId=1111, UserName=me#me.com, IPAddr=(empty), AccountId=22222, AccountName=test-account, ProjectId=test-project
How can I now access the keys like EventType, FriendlyType, etc.? I assume that I have to convert this output at first to a valid JSON, but I am currently baffled.
In case that you are not able to receive the Message data as a JSON, a way to handle the situation is convert the message string into a dict <key>:<value>:
message_as_dict = dict(map(lambda var: var.strip().split("=") ,message.split(",")))
NOTICE the .strip() in order to remove the spaces on the beginning of the key.
That shoud create a dictionary with the following structure:
{'EventType': 'Delete', 'FriendlyType': 'was deleted', 'Timestamp': '2021-11-08T15:30:45Z', 'UserId': '1111', 'UserName': 'me#me.com', 'IPAddr': '(empty)', 'AccountId': '22222', 'AccountName': 'test-account', 'ProjectId': 'test-project'}
Then you can access to the values with, for example:
print(message_as_dict["UserName"])
> me#me.com
you can parse your string spliting and then use it to create a dict. Maybe it's not the best solution but it's a simple one.
response = {
'Type': 'Notification',
'MessageId': 'xxx',
'TopicArn': 'xxx',
'Subject': 'xxx',
'Message': 'EventType=Delete, FriendlyType=was deleted, Timestamp=2021-11-08T15:30:45Z, UserId=1111, UserName=me#me.com, IPAddr=(empty), AccountId=22222, AccountName=test-account, ProjectId=test-project',
'Timestamp': '2021-11-08T15:30:46.214Z',
'SignatureVersion': '1'
}
keyVals = [el.split('=') for el in response['Message'].split(', ')]
subdict = {}
for key,val in keyVals:
subdict[key] = val
As mentioned in one of the answer, you can parse your Message string, but I too feel it won't be the best solution. What I noticed is that your JSON is not in proper format. See below for proper JSON you should be getting from your API.
{
"Type": "Notification",
"MessageId": "xxx",
"TopicArn": "xxx",
"Subject": "xxx",
"Message": {
"EventType": "Delete",
"FriendlyType": "was deleted",
"Timestamp": "2021-11-08T15:30:45Z",
"UserId": "1111",
"UserName": "me#me.com",
"IPAddr": "(empty)",
"AccountId": "22222",
"AccountName": "test-account",
"ProjectId": "test-project"
},
"SignatureVersion": "1"
}
Once you are able to get this output, you may further access nested objects. For example, to access FriendlyType from Message, you can simply say, body.Message.FriendlyType. body here means your entire JSON object.
You could do it by splitting the 'Message' string up into (key, value) pairs and constructing a dictionary from them:
from pprint import pprint
output = {'Type': 'Notification',
'MessageId': 'xxx',
'TopicArn': 'xxx',
'Subject': 'xxx',
'Message': 'EventType=Delete, FriendlyType=was deleted, '
'Timestamp=2021-11-08T15:30:45Z, UserId=1111, UserName=me#me.com, '
'IPAddr=(empty), AccountId=22222, AccountName=test-account, '
'ProjectId=test-project',
'Timestamp': '2021-11-08T15:30:46.214Z',
'SignatureVersion': '1'}
msg_dict = dict(pair.split('=') for pair in output['Message'].split(', '))
pprint(msg_dict, sort_dicts=False)
Output:
{'EventType': 'Delete',
'FriendlyType': 'was deleted',
'Timestamp': '2021-11-08T15:30:45Z',
'UserId': '1111',
'UserName': 'me#me.com',
'IPAddr': '(empty)',
'AccountId': '22222',
'AccountName': 'test-account',
'ProjectId': 'test-project'}

How to fix "'User' object is not subscriptable"

I am trying to write some Python code, that gets the users Gitlab Profile picture/avatar to be sent in a Discord Embed later on in the code. However, when i try to read the json that the Gitlab API returns but i receive the error "'User' object is not subscriptable" this json doesnt look like other jsons returned by the Gitlab API.
I have tried to use Attributes but i still receive the same error, i have also tried just to read it but i still receive the same error.
import gitlab
import json
# private token or personal token authentication
gl = gitlab.Gitlab('URL', private_token='')
project = gl.projects.get(13)
json_data = project.tags.list(order_by='updated', sort='desc')
newest_tagjson = (json_data[0].attributes)
latesttag = newest_tagjson["name"]
name1 = newest_tagjson["commit"]["author_name"]
projectid = newest_tagjson["project_id"]
footer1 = "Panel"
if name1 == "------":
ID = 16
user = gl.users.get(ID)
print(user)
user2 = (user['avatar_url'].attributes)
i should receive a clean json that i can read but instead i recieve this in the print
<class 'gitlab.v4.objects.User'> => {'id': 16, 'name': '', 'username': '', 'state': 'active', 'avatar_url': 'https://URL.io/uploads/-/system/user/avatar/16/avatar.png', 'web_url': '', 'created_at': '2019-01-29T18:30:53.819Z', 'bio': ' \r\n', 'location': ', United Kingdom', 'public_email': '', 'skype': '', 'linkedin': '', 'twitter': '', 'website_url': '', 'organization': ''}
and i cannot read this.
The error seems pretty clear: the result of calling gl.users.get(ID) is not a Python dictionary, so you can't access keys with subscripts as in user['avatar_url']. You can access attributes using Python's dot notation, as in user.avatar_url.
You can of course extract the information you want into a Python dictionary:
>>> user_dict = {k: getattr(user, k) for k in
... ['id', 'name', 'state', 'avatar_url', 'web_url']}
>>> user_dict
{'id': 28841, 'name': 'Lars Kellogg-Stedman', 'state': 'active', 'avatar_url': 'https://secure.gravatar.com/avatar/1c09a8d9e719f9d13b6c99f6bb2637d8?s=80&d=identicon', 'web_url': 'https://gitlab.com/larsks'}
And then you can serialize this to JSON:
>>> print(json.dumps(user_dict, indent=2))
{
"id": 28841,
"name": "Lars Kellogg-Stedman",
"state": "active",
"avatar_url": "https://secure.gravatar.com/avatar/1c09a8d9e719f9d13b6c99f6bb2637d8?s=80&d=identicon",
"web_url": "https://gitlab.com/larsks"
}
The Python gitlab module wraps the gitlab API in a variety of managers designed to make certain things easier, but if your goal is to serialize things to JSON it might be easier to simply call the REST API yourself:
>>> import requests
>>> session = requests.Session()
>>> session.headers['private-token'] = your_private_token
>>> res = session.get('https://gitlab.com/api/v4/users/28841')
>>> res.json()
{'id': 28841, 'name': 'Lars Kellogg-Stedman', 'username': 'larsks', 'state': 'active', 'avatar_url': 'https://secure.gravatar.com/avatar/1c09a8d9e719f9d13b6c99f6bb2637d8?s=80&d=identicon', 'web_url': 'https://gitlab.com/larsks', 'created_at': '2014-04-26T01:52:14.000Z', 'bio': '', 'location': None, 'public_email': '', 'skype': '', 'linkedin': '', 'twitter': 'larsks', 'website_url': 'http://blog.oddbit.com/', 'organization': None}

How to create a user with credentials in okta using python sdk

Is there any way to create okta user with credentials using python
Creates a user without a recovery question & answer. The new user will immediately be able to login after activation with the assigned password. This flow is common when developing a custom user registration experience.
curl -v -X POST \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: SSWS ${api_token}" \
-d '{
"profile": {
"firstName": "Isaac",
"lastName": "Brock",
"email": "isaac.brock#example.com",
"login": "isaac.brock#example.com",
"mobilePhone": "555-415-1337"
},
"credentials": {
"password" : { "value": "tlpWENT2m" }
}
}' "https://${org}.okta.com/api/v1/users?activate=false"
This one is by using Curl
Using the requests library in Python:
import requests
url = '{{org}}.okta.com/api/v1/users'
headers = {
'accept': 'application/json',
'authorization' : 'SSWS {{api_token}}',
'content-type': 'application/json'
}
body = {
'profile': {
'firstName': 'Isaac',
'lastName': 'Brock',
'email': 'isaac#{{email_suffix}}',
'login': 'isaac#{{email_suffix}}'
},
'credentials': {
'password' : { 'value': '{{password}}' }
}
}
r = requests.post(url, headers=headers, json=body)
# r.json
Using the Okta Python SDK, you need to create a client first, then call the create_user() method.
from okta import UsersClient
from okta.models.user import User
usersClient = UsersClient("https://{{org}}.okta.com", "{{api_token}}")
user = User(login='isaac#{{email_suffix}}',
email='isaac#{{email_suffix}}',
firstName='Isacc',
lastName='Brock')
user = usersClient.create_user(user, activate=False)
Based on Okta API reference guide for create user (here), And Okta Python SDK docs for create user (here):
There are two options, that worked for me:
Pass data as dict:
import asyncio
from okta.client import Client as OktaClient
from okta.models import User, UserProfile
config = {
'orgUrl': 'https://your_domain.okta.com',
'token': 'your_token'
}
async def main():
async with OktaClient(config) as client:
data = {
"profile": {
"firstName": "Omid",
"lastName": "Raha",
"email": "omid#example.com",
"login": "omid#example.com",
"mobilePhone": "{123}-{456}-{789}"
},
"credentials": {
"password": {"value": "Password!123"}
}
}
res = await client.create_user(data, {'activate': True, })
print('user created. info: {}'.format(res))
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Or pass data as okta object model:
import asyncio
from okta.client import Client as OktaClient
from okta import models
config = {
'orgUrl': 'https://your_domain.okta.com',
'token': 'your_token'
}
# Create Password
password = models.PasswordCredential({
'value': 'Password!123'
})
# Create User Credentials
user_creds = models.UserCredentials({
'password': password
})
# Create User Profile and CreateUser Request
user_profile = models.UserProfile()
user_profile.first_name = 'Omid'
user_profile.last_name = 'Raha'
user_profile.email = 'omid#example.com'
user_profile.login = 'omid#example.com'
create_user_request = models.CreateUserRequest({
'credentials': user_creds,
'profile': user_profile
})
async def main():
async with OktaClient(config) as client:
res = await client.create_user(create_user_request, {'activate': True, })
print('User created, info: {}'.format(res))
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Response (same for both methods):
User created, info:
({
'embedded': None,
'links': None,
'activated': '2022-08-17T10:05:02.000Z',
'created': '2022-08-17T10:05:02.000Z',
'credentials': {
'password': {'hash': None, 'hook': None, 'value': None},
'provider': {'name': 'OKTA', 'type': <AuthenticationProviderType.OKTA: 'OKTA'>},
'recovery_question': None
},
'id': '23d83739Ejdj',
'last_login': None,
'last_updated': '2022-08-17T10:05:02.000Z',
'password_changed': '2022-08-17T10:05:02.000Z',
'profile': {
'city': None,
'costCenter': None,
'countryCode': None,
'department': None,
'displayName': None,
'division': None,
'email': 'omid#example.com',
'employeeNumber': None,
'firstName': 'Omid',
'honorificPrefix': None,
'honorificSuffix': None,
'lastName': 'Raha',
'locale': None,
'login': 'omid#example.com',
'manager': None,
'managerId': None, 'middleName': None,
'mobilePhone': '123-456-789',
'nickName': None, 'organization': None,
'postalAddress': None,
'preferredLanguage': None,
'primaryPhone': None, 'profileUrl': None,
'secondEmail': None, 'state': None,
'streetAddress': None,
'timezone': None, 'title': None,
'userType': None, 'zipCode': None
},
'status': <UserStatus.ACTIVE: 'ACTIVE'>,
'status_changed': '2022-08-17T10:05:02.000Z',
'transitioning_to_status': None,
'type': {
'links': None,
'created': None,
'created_by': None,
'default': None,
'description': None,
'display_name': None,
'id': '83Dm32dje3',
'last_updated': None,
'last_updated_by': None,
'name': None
}
},
<okta.api_response.OktaAPIResponse object at 0x7fd5e286f130>, None
)

Categories