i try to delete all attachments from a site with confluence.delete_attachment(page_id, filename, version), butt it throws always the same exception:
requests.exceptions.HTTPError: 401 Client Error: Authorization Required for url:
I am currently deleting the attachments as follows:
from atlassian import Confluence
confluence_url = 'https://xxx/confluence/'
confluence_usr = os.environ.get('CONFLUENCE_CREDS_USR')
confluence_psw = os.environ.get('CONFLUENCE_CREDS_PSW')
confluence = Confluence(url=confluence_url, username=confluence_usr, password=confluence_psw)
# Check site response, if site not reachable, check 5 times every 5 sec
response = resilient_confluence_http_get_request(f'{confluence_url}rest/api/content/{page_ids[csv_file]}')
# Check site response, if site not reachable, check 5 times every 5 sec
attachment = confluence.get_attachments_from_content(page_ids[csv_file])
print(f"attachment type: {type(attachment)}")
print(f"attachment content:\n {attachment}\n\n")
att_to_del = []
indices = 0
for i in attachment['results']:
print(f"id type: {type(attachment['results'][indices]['id'])}")
att_to_del.append(attachment['results'][indices]['id'])
indices += 1
print(f"delete attachments with id's {att_to_del}")
for id_to_delete in att_to_del:
response = requests.delete(f'https://xxx/confluence/rest/api/content/{id_to_delete}',
auth=(confluence_usr, confluence_psw))
The delete function is the only one that doesn't work. What am I doing wrong?
Here i try to delete with confluence.delete_attachment(...):
def response_wait_repeat():
attachments = confluence.get_attachments_from_content('my_site_id')
print(attachments)
confluence.delete_attachment('my_site_id', 'my_filename', version=None)
I assume you are using atlassian-python-api
as the examples on the pypi documentation, you first need to create a connection to the confluence:
from atlassian import Confluence
confluence = Confluence(
url='http://localhost:8090',
username='admin',
password='admin')
status = confluence.create_page(
space='DEMO',
title='This is the title',
body='This is the body. You can use <strong>HTML tags</strong>!')
print(status)
If you are still getting this error (401 Authorization Required) I would check manually in confluence, whether you have the permission to do these such actions.
It's probably the case, because you are saying the only action you cannot preform is delete.
otherwise I would contact the confluence admin.
Related
I have completed the steps provided by Google to implement push notifications using the Drive API. Everything goes as described except I do not receive any notifications from Google whenever a change occurs (listed as Step 4 below).
Below is a summary of the steps I followed and the results at each stage:
Step 1 (Success): Verify that you own the domain
I went to Search Console as directed and successfully verified the site.
Step 2 (Success): Register your domain
I visited the Domain Verification page and added my domain in the API Console. Google API Console updated to show the list with my desired domain.
I have a valid SSL certificate from GoDaddy for my domain and have verified that as well.
Step 3 (Success): Created my notification channel
Using the python SDK, I created the channel and got back a response from Google. The python code below shows how I did this. Note: The address included in my request directs Google to send notifications to my Flask website that I am hosting in Google's App Engine. I am showing the domain as my_domain.com here for privacy as I am in the process of bringing up the site.
channel_id = str(uuid.uuid4())
body = {
'kind': 'api#channel',
'id': channel_id,
'type': 'web_hook',
'address': "https://my_domain.com/notifications"
}
try:
start_page_token = service.changes().getStartPageToken().execute().get('startPageToken');
print(service.changes().watch(pageToken=start_page_token, body=body).execute())
except Exception as e:
print('Exception: {}'.format(e))
And here is the response from Google:
{u'resourceId': u'vTMwJWl7a23Af1LK1TpJZ38eO_0', u'kind': u'api#channel', u'expiration': u'1538433975000', u'id': u'dce14225-95c8-42a7-9945-4fed1604c848', u'resourceUri': u'https://www.googleapis.com/drive/v3/changes?alt=json&includeCorpusRemovals=false&includeRemoved=true&includeTeamDriveItems=false&pageSize=100&pageToken=4919&restrictToMyDrive=false&spaces=drive&supportsTeamDrives=false&alt=json'}
Step 4 (Failed): Process a notification from Google
I am running a Flask website on App Engine and created an app.route to receive notifications from Google. I've included the code below. I never receive anything at this URL.
#app.route('/notifications')
def notifications():
print('in notifications()')
try:
chan_id = request.args.get('X-Goog-Channel-ID', 'empty')
msg_num = request.args.get('X-Goog-Message-Number', 'empty')
rid = request.args.get('X-Goog-Resource-ID', 'empty')
state = request.args.get('X-Goog-Resource-State', 'empty')
resource_uri = request.args.get('X-Goog-Resource-URI', 'empty')
goog_changed = request.args.get('X-Goog-Changed', 'empty')
goog_chan_exp = request.args.get('X-Goog-Channel-Expiration', 'empty')
goog_chan_token = request.args.get('X-Goog-Channel-Token', 'empty')
print('chan_id: {}'.format(chan_id))
print('msg_num: {}'.format(msg_num))
print('rid: {}'.format(rid))
print('state: {}'.format(state))
print('resource_uri: {}'.format(resource_uri))
print('goog_changed: {}'.format(goog_changed))
print('goog_chan_exp: {}'.format(goog_chan_exp))
print('goog_chan_token: {}'.format(goog_chan_token))
except Exception as e:
print('notifications() exception: {}'.format(e))
print('leaving notifications()')
return jsonify(result='done')
I'm not sure if this is the problem but, when I tried Google Drive push notifications, I didn't use the SDK. I only made a POST request as it shows in the documentation.
Could you try to make a POST request to "https://www.googleapis.com/drive/v3/changes/watch" instead of using service.changes().watch()?
You will need an access_token for the request, but I believe you wont need to send a startPageToken as they don't use it in their example:
I hope it helps!
What is the way to pull out all emails from Gmail?
I did full_sync, but that didn't return all of my email - only about 3000 emails, while I know I have more. In the documentation they did not mention about this.
My code snippet:
history = service.users().history().list(
userId='me',
startHistoryId=start_history_id,
maxResults=500,
labelId='INBOX'
).execute()
if "history" in history:
try:
for message in history["history"]:
batch.add(
service.users().messages().get(userId='me', id=message["messages"][0]["id"]),
callback="somecallbak",
request_id=request_id
)
batch.execute()
while 'nextPageToken' in history:
If you are doing a full sync, you should refer to this documentation, that recommends two steps:
listing all the messages with the users.messages.list method
for each of the entry get the required information using the users.messages.get method
So you don't need use the users.history.list as you will have an hard time finding the startHistoryId from which to start.
You can achieve this with a snipped similar to the one below (tested and working on my python 3.x console). As suggested by others I used the python client pagination and batch request functionalities.
from httplib2 import Http
from googleapiclient.discovery import build
from oauth2client import client, tools, file
# callback for the batch request (see below)
def print_gmail_message(request_id, response, exception):
if exception is not None:
print('messages.get failed for message id {}: {}'.format(request_id, exception))
else:
print(response)
# Scopes
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly', ]
# where do we store our credentials?
creds_store = file.Storage('gmail-list.json')
start_creds = creds_store.get()
# standard oauth2 authentication flow
if not start_creds or start_creds.invalid:
# client_id.json is exported from your gcp project
start_flow = client.flow_from_clientsecrets('client_id.json', SCOPES)
start_creds = tools.run_flow(start_flow, creds_store)
# Gmail SDK
http = Http()
gmail_sdk = build('gmail', 'v1', http=start_creds.authorize(http))
# messages.list parameters
msg_list_params = {
'userId': 'me'
}
# messages.list API
message_list_api = gmail_sdk.users().messages()
# first request
message_list_req = message_list_api.list(**msg_list_params)
while message_list_req is not None:
gmail_msg_list = message_list_req.execute()
# we build the batch request
batch = gmail_sdk.new_batch_http_request(callback=print_gmail_message)
for gmail_message in gmail_msg_list['messages']:
msg_get_params = {
'userId': 'me',
'id': gmail_message['id'],
'format': 'full',
}
batch.add(gmail_sdk.users().messages().get(**msg_get_params), request_id=gmail_message['id'])
batch.execute(http=http)
# pagination handling
message_list_req = message_list_api.list_next(message_list_req, gmail_msg_list)
As suggested in this link, you may use batch requests.
Use batch and request 100 messages at a time. You will need to make 1000 requests but the good news is that's quite fine and it'll be easier for everyone (no downloading 1GB response in a single request!).
Also based from this thread, you could save the next page token on every request and use it in your next request. If there is no next page token in the response, you know that you have gotten all messages.
I'm trying to get service(SAP mobile document) via CMIS.
In service web client i can create folder and add file.
Via CMIS I can auth and get repo's list, but that's all.
For other methods I get cmislib.exceptions.PermissionDeniedException: Error 403
I used this doca http://chemistry.apache.org/python/docs/
from cmislib import *
client = CmisClient('https://service/mcm/b/atom', 'user', 'pwd')
print client.getRepositories()
#REPO
#repo = client.defaultRepository
repo = client.getRepository('573f7fc4-2c76-49a2-b63c-d39e370edfde')
print repo.name
#FOLDER
rFolder = repo.rootFolder
print rFolder.id
#denied
#rFolder.getChildren()
#acl = rFolder.getACL()
#print rFolder.getName()
#newFolder = rFolder.createFolder('testfolder')
denied returns
cmislib.exceptions.PermissionDeniedException: Error 403 at https://url/mcm/b/atom/573f7fc4-2c76-49a2-b63c-d39e370edfde/id?id=906f3ae3-a4c9-3210-7292-c840e0cff769&filter=&includeAllowableActions=false&includeACL=false&includePolicyIds=false&includeRelationships=&renditionFilter=
*the same error for default repo
#repo = client.defaultRepository
SAP Mobile Documents requires cookies. Turn cookies on on the client side and those exceptions will disappear.
See http://help.sap.com/saphelp_mdocs10/helpdata/en/0e/432781e0c646a09602a4aab786734d/content.htm?frameset=/en/d5/476115e8264a33a52fd59d260892cb/frameset.htm¤t_toc=/en/69/ec44f07b34409a8b65005f51315f1a/plain.htm&node_id=105 how to the authentication works.
I'm looking for a possibility to get a followers and following list in JSON format via web request (in the same way as on the Instagram web site).
For example, I can login via requests, and get user info:
def get_user_info(self, user_name):
url = "https://www.instagram.com/" + user_name + "/?__a=1"
try:
r = requests.get(url)
except requests.exceptions.ConnectionError:
print 'Seems like dns lookup failed..'
time.sleep(60)
return None
if r.status_code != 200:
print 'User: ' + user_name + ' status code: ' + str(r.status_code)
print r
return None
info = json.loads(r.text)
return info['user']
I tried to see what request chrome send to server, but was unsuccessful.
The question is: how to prepare a similar get or post request to retrieve followers list without the Instagram API?
GraphQL queries with query_hash = "58712303d941c6855d4e888c5f0cd22f" (followings) and "37479f2b8209594dde7facb0d904896a" (followers) return this information. With being logged in, do a GET query to instagram.com/graphql/query with parameters query_hash and variables, where variables is a JSON-formatted set of variables id (user id, as in the return dictionary of your get_user_info() function), first (a page length, it seems the current maximum is 50) and in subsequent requests after set to the end_cursor in the previous response dictionary.
Alternatively, the Instaloader library provides a convenient way to login and then programmatically access a profile's followers and followings list.
import instaloader
# Get instance
L = instaloader.Instaloader()
# Login or load session
L.login(USER, PASSWORD) # (login)
L.interactive_login(USER) # (ask password on terminal)
L.load_session_from_file(USER) # (load session created w/
# `instaloader -l USERNAME`)
# Obtain profile metadata
profile = instaloader.Profile.from_username(L.context, PROFILE)
# Print list of followees
for followee in profile.get_followees():
print(followee.username)
# (likewise with profile.get_followers())
Besides username, the attributes full_name, userid, followed_by_viewer and many more are defined in the Profile instance that is returned for each followee.
Easy(just replace _a with __a)
'https://www.instagram.com/'+user_name+'/followers/?_a=1'
'https://www.instagram.com/'+user_name+'/following/?_a=1'
I'm unable to post to my website's facebook page wall via my facebook application even though it has the publish_stream, offline_access & manage_pages permission for posting to the page (along with its correct access token).
The application is able to post to '/page_id/links/' but not to '/page_id/feed/'.
See the code below:
graph = facebook.GraphAPI(settings.FB_PAGE_ACCESS_TOKEN_FOR_FB_APP)
attachment = {}
message = 'Hello! check the link!'
site = Site.objects.get_current()
attachment['name'] = '%s' % idea.title
attachment['link'] = 'http://%s%s' %(site,idea.get_absolute_url())
attachment['caption'] = 'addressing problem "%s"' % idea.problem
attachment['description'] = '%s' % striptags(idea.desc)
attachment['properties'] = {'See more': {'text':'Featured ideas', 'href':'http://%s' % site}}
# this works; posts to /fbpage/links/
graph.put_object(settings.FACEBOOK_PAGE, "links", message=message, **attachment)
# this does not work; posts to /fbpage/feed/
graph.put_wall_post(message, attachment, settings.FACEBOOK_PAGE)
I posted my solution to get the right access token in this question:
How to get the access token to post on behalf of a facebook page via a custom application?