Unable to access notion comments via API/python - python

I'm trying to read the comments on a database entry in notion but I can't figure out how I need to make the request.
import requests
_url = 'https://api.notion.com/v1/comments'
_headers = {"Authorization": _auth,
"Notion-Version": "2021-08-16"}
_data = {'block_id': _page_id}
_results = requests.post(_url, headers=_headers, data=json.dumps(_data))
_data = _results.json()
These results I get back are something like this:
{u'code': u'validation_error',
u'message': u'body failed validation. Fix one:\nbody.parent should be defined, instead was `undefined`.\nbody.discussion_id should be defined, instead was `undefined`.',
u'object': u'error',
u'status': 400}
I'm trying to follow the docs here https://developers.notion.com/reference/retrieve-a-comment but I'm not sure how it translates into python.
Has anyone managed to do this?

If you are reading/getting data from the API, you should use GET, not POST.
To translate the API to Python code, you will do something like this. Notice that the block id is a query parameter not in the request body.
_url = 'https://api.notion.com/v1/comments'
_headers = {"Authorization": _auth,
"Notion-Version": "2021-08-16"}
_query = {'block_id': _page_id}
_results = requests.get(_url, headers=_headers, params=_query)
_data = _results.json()
You also need to ensure that you have added the integration to the notion page.
Run the code, you will get the response like this, (in my case, I don't have any comments on the page).
{'object': 'list', 'results': [],
'next_cursor': None, 'has_more': False,
'type': 'comment', 'comment': {}}

Related

API response does not return OrderArray.Order.SellerUserID

I have a question about ebay trading api.
I'm trying to get the information about my purchases so I can follow up on late/failed deliveries.
I have managed to get almost all of the information I need, however I just can't seem to work out how to get eaby-api to return the seller user id.
api = Trading(
config_file=None,
appid=load_settings['appid'],
certid=load_settings['certid'],
devid=load_settings['devid'],
token=load_settings['token'],
timeout=None
)
response = api.execute('GetOrders', {
'CreateTimeFrom': create_time_from,
'CreateTimeTo': create_time_to,
'OrderRole': 'Buyer',
'DetailLevel': 'ReturnAll',
'Pagination': {
'EntriesPerPage': 100,
'PageNumber': page
}
})
data = response.dict()
print(data)
I read in the docs that to get OrderArray.Order.SellerUserID you have to change the DetailLevel
However even if I set 'DetailLevel': 'ReturnAll' I do not get SellerUserID in my response.
Is there something I'm over looking?
https://developer.ebay.com/devzone/xml/docs/reference/ebay/getorders.html#DetailLevel
using eBay API getOrders, without any sdk
it returns correctly the SellerUserID even without setting DetailLevel to ReturnAll
Looks like the information was there, just not in the place the docs said.
I found it at
response.dict()["OrderArray"]["Order"]['MonetaryDetails']['Payments']['Payment']['Payee']

Meraki API call get.organisation/uplinks find failed connections and translate networkid into a network name

I've been looking for a few weeks and nowhere have i found anything that could help me with this specific problem.
I got a large output from an API call (Meraki) i'm looking to extract certain features out of the list.
Task: read output from API call, loop through output until status 'failed' is detected and print the interface and networkId of that item turn the networkId into a network name from a predefined list, and continue to print all "failed interfaces" till end of output.
The API call gets the entire organisation and i want to match the list of networkid's with Network names (since they aren't added in the same API call) so its readable what network has which interface that failed.
The output contains a lot of data , and i don't need all of those output values like IP, gateway, DNS, etc.
an example of the output from the API call:
{'networkId': 'A_1234567890', 'serial': 'A1B2-C3D4-E5F6', 'model': 'MX64', 'lastReportedAt': '2021-01-01T10:00:00Z', 'uplinks': [{'interface': 'wan1', 'status': 'active', 'ip': '192.168.1.2', 'gateway': '192.168.1.1', 'publicIp': '192.168.1.3', 'primaryDns': '8.8.8.8', 'secondaryDns': '8.8.4.4', 'ipAssignedBy': 'static'}, {'interface': 'wan2', 'status': 'ready', 'ip': '172.16.1.2', 'gateway': '172.16.1.1', 'publicIp': '172.16.1.3', 'primaryDns': '8.8.8.8', 'secondaryDns': '8.8.4.4', 'ipAssignedBy': 'static'}]}
This is one network of which there are 50 in this organisation i want to check the status of.
I'm pretty new to Python and I've tried using while loops to sift through the output to find the failed status but i cant output the whole network's information connected to it, I've looked at but most examples are using small predefined lists of separate words or numbers.
the API call im using:
(found the template and modified where necessary to get a total list of all networks in my organisation)
import requests
url = "https://api.meraki.com/api/v1/organizations/{ORG_ID}/uplinks/statuses"
payload = None
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"X-Cisco-Meraki-API-Key": "API_KEY"
}
response = requests.request('GET', url, headers=headers, data = payload)
pprint(response.json())
Answer given in the another post, by #Szabolcs:
net_names = {"A_1234567890": "Name"}
for network_data in json_data:
network_id = network_data.get("networkId")
for uplink_data in network_data.get("uplinks", []):
if uplink_data["status"] == "failed":
print(
"network ID:",
network_id, ""
"Network:",
net_names.get(network_id, "n/a"),
"- Interface:",
uplink_data["interface"],
"- failed",)
Does all i want.
Based on your sample output, looks like you have got the network ID only once in response and interface and is seen many times as part of Uplink attribute,
Hence, you can parse the API response as a Json object and have the network names - network ID mapping in a dictionary and do something like below to get the failed status
net_names = {'A_1234567890':'abc', 'b':'xyz'}
network_id =response_json.get('networkId')
for item in response_json['uplinks']:
if item['status'] == "failed":
print('network ID:', network_id,'network_name:',net_names.get(network_id), 'Interface:',item['interface'])

Jira API Assignee not populating with "name" anymore, instead needs "accoundId"

I'm working with Python 3.x
Previously, I had a function to create tickets that looks like this
def jira_incident(jira_subject, jira_description):
user = "username"
apikey = 'apikey'
server = 'https://serverName.atlassian.net'
options = {
'server': server,
'verify': False
}
issue_dict = {
'project': {'key': 'project_name'},
'summary': str(jira_subject),
'description': str(jira_description),
'issuetype': {'name': 'Incident'},
'assignee': {'name': my_username},
'priority': {'name': 'Low'},
'customfield_10125':
{'value': 'Application Ops'}
}
jira = JIRA(options, basic_auth=(user, apikey))
new_issue = jira.create_issue(fields=issue_dict)
return new_issue
my_username is a global variable that's used for other things as well.
Anyway, the assignee is no longer working as of about 2 days ago. I did some googling and found that it now needs the accountId instead of the name, I can get this via the web UI by leaving a comment as #'ing someone in a comment. As a temporary solution I've populated a dictionary to reference (and that works), however I'd like to make this more dynamic for future proofing the script.
'assignee': {'accountId': jira_dict[my_username]},
I can't seem to really find any documentation on looking up the accountId from the name, and I figured I'd go ahead and ask the community to see if anyone else has run into/solved this issue.
I was thinking about just writing a new function that performs this query for me, then returns the accountId.
EDIT
I did find this:
import requests
from requests.auth import HTTPBasicAuth
import json
url = "/rest/api/3/user/bulk/migration"
auth = HTTPBasicAuth("email#example.com", "<api_token>")
headers = {
"Accept": "application/json"
}
response = requests.request(
"GET",
url,
headers=headers,
auth=auth
)
print(json.dumps(json.loads(response.text), sort_keys=True, indent=4, separators=(",", ": ")))
However it 404's on me, I add the server address to the beginning of the url, and replace user, with the username in question.
Okay, I found a solution, it's not an elegant solution, but it does exactly what I need it to. So here is the new function:
def jira_account_id_from_username(username):
r = requests.get('https://serverName.atlassian.net/rest/api/3/user?username=' + username, auth=("username",api_key), verify=False)
value = re.search('"accountId":"(.*?)",', str(r.text)).group(1)
return value
I strongly encourage you to not rely on the username anymore. The endpoint you are using is deprecated, see also https://developer.atlassian.com/cloud/jira/platform/deprecation-notice-user-privacy-api-migration-guide/.
The "new" or probably better way is to use the /user/search endpoint as described here: https://developer.atlassian.com/cloud/jira/platform/rest/v3/#api-rest-api-3-user-search-get There you can define a query that is matching against certain properties of a user (displayName or emailAddress), or search for the accountId if you already have it. Therefore, if you are linking users from the cloud to some other "user directory" (or just a scripts where you have stored some usernames), replace it by using either email address or accountId so you can properly link your users.

PagerDuty assignments list empty

How can I get "assignments" key of the incidents in PagerDuty? I have a python script which returns info on particular incident, but the list with assignments is empty.
#!/usr/bin/env python
import requests
import json
API_KEY = 'iiiiiiiiiiiiiiiiii'
# incident ID
ID = 'PPPPP'
def get_incident():
url = 'https://api.pagerduty.com/incidents/{id}'.format(id=ID)
headers = {
'Accept': 'application/vnd.pagerduty+json;version=2',
'Authorization': 'Token token={token}'.format(token=API_KEY)
}
params = {
'include': 'assignees',
'time_zone': 'Europe/Sofia'
}
r = requests.get(url, headers=headers,data=json.dumps(params))
print ('Status Code: {code}'.format(code=r.status_code))
print (r.json())
if __name__ == '__main__':
get_incident()
In their documentation here there are entries for that key, see on the picture bellow:
How can I achieve that?
Based on experimentation, it appears that assignments are only populated while an incident is still active. I just queried /incidents/id for an incident in the triggered state and in the resolved state, the triggered one shows an assignment while the resolved one does not.
It's kind of frustrating, because I want to look at the LogEntrys for an incident via their API and I haven't figured that out yet.
The alert_counts field always seems to contain zeros too, which doesn't make any sense.

How to unsubscribe / delete list members using Mailchimp3 in Python?

I am using mailchimp3 in Python. I managed to make batch insertion of users using this function:
client = MailChimp(USERNAME, APIKEY)
def fill_list(list_id, subscribers_data):
data = {'operations': create_subscriptions_data(list_id, subscribers_data)}
client.batches.create(data)
def create_subscriptions_data(list_id, users_data):
return [{'method': 'PUT',
'path': 'lists/{}/members/{}'.format(list_id, str(md5(user['email_address'].encode('utf-8')))),
'body': json.dumps(user)} for user in users_data]
Here is how one user dict looks like:
{"email_address": "user#somemail.com", "status": "subscribed"}
Then I wanted to use similar method to unsubscribe list of users. To achieve that I tried to use the same logic, just to change the user objects. Now, I used this user format:
{"email_address": "user#somemail.com", "status": "unsubscribed"}
It doesn't update the subscribe status. When I deleted all users manually (using the web interface) and tried the same command I successfully created users with "status": "unsubscribed". I am wondering why this approach can't change the status? I tried also using POST instead of PUT, but it didn't work. Any idea what can be the issue?
I used this reference https://devs.mailchimp.com/blog/batch-operations-and-put-in-api-v3-0/ and it mentions that this approach should work fine for updates as well.
Thank you in advance!
The only way to unsubscribe an already subscribed user will be to update with a list id and an MD5 hash of the lowercase version of the list member’s email address.
client.lists.members.update('LIST_ID', 'MD5 HASH', {"status":
"unsubscribed"})
Actually, I was using some wrong functions, so here is the fixed code. I also had some problems with the size of the batches. The maximum batch size is 500, so I did some splits of the data across several batches.
Here is a simple code how the insertion should be done:
client = MailChimp(USERNAME, APIKEY)
def _update_list(list_id: str, members_data: list):
client.lists.update_members(list_id, {'members': members_data, 'update_existing': True})
Each member in members_data has data like this:
mailchimp_user = {
'email_address': user.email,
'status': user.subscription_status,
'merge_fields': {
'FNAME': user.first_name,
'LNAME': user.last_name
},
'interests': {}
}
And here comes the most important function:
def fill_in_multiple_batches(list_id, mailchimp_members):
step_size = 400
for i in range(0, len(mailchimp_members), step_size):
batch_start_idx = i
batch_end_idx = min(i + step_size, len(mailchimp_members))
this_batch_of_members = mailchimp_members[batch_start_idx:batch_end_idx]
client.lists.update_members(list_id, {'members': members_data, 'update_existing': True})
After that, in the main of the script:
if __name__ == '__main__':
fill_in_multiple_batches('your_list_id', your_data_list)

Categories