I am new using python library shareplum. I have a sharepoint site with list named "Events". Inside that list there is a list item which is a folder with list items inside (EventsXXXX). I manage to update the Events list with a new item but I do not know how to move this item to EventsXXXX.
This is a snippet of my code:
user, password = 'xxxxx', 'xxxxxx'
auth = HttpNtlmAuth('yyyyyyy\\'+user, password)
site = Site('https://yyyyyyy/lib/zzzzz', version=Version.v2016, auth=auth)
folder = 'https://yyyyyyy/lib/zzzzz/Lists/Events/EventsXXXX'
sp_list = site.List('Events')
task_list = [{'Content Type': ......}]
sp_list.UpdateListItems(task_list, 'New', False)
The result is for Events list:
ID Title Project Fields
9928 XXXXXX1 YYYYY ZZZZZ
1525 EventsXXXX YYYYY KKKKK --> this is an list item but it is a folder containing list items
as ID 9928
Errors produced:
I cannot access EventsXXXX using sp_folder = site.Folder(folder)
Shareplum HTTP Post Failed : 401 Client Error: Unauthorized for url: https://xxxx/lib/xxxxx/_api/web/folders
EventsXXXX is not recognised when doing sp_list2 = site.List(folder)
Shareplum HTTP Post Failed : 500 Server Error: Internal Server Error for url: https://xxxx/lib/xxxx/_vti_bin/lists.asmx
I would appreciate any help to explain how to move item ID 9928 into the folder 1525 or how to save item ID 9928 into folder 1525, considering the above errors.
Related
I want to send Send direct message to specific user in ms teams through python with Odoo?
This is a little more complicated task, but definitely doable. Sending an individual message using python is not as easy as using Webhook to send the message in Teams. You have to go through Authentication, get your token and then send the chat. Here are the steps that I used to get this to work using selenium to get the Authentication and then using requests.post to send individual massage.
By the way if you thought getting authentication with Microsoft is easy you are 100% wrong, here is the link to getting access token from microsoft https://learn.microsoft.com/en-us/graph/auth-v2-user
After you register your app with Azure you can use the following cod to get the Authentication token using slenium.
Set up Selenium
import gc
gc.disable() # 03/23/2022 added this one to prevent trash collection and avoide crashing the notebooks
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.service import Service
from selenium.common.exceptions import WebDriverException # to catch WebDriverException after changing the host from postman to local
Options.binary_location = "/usr/bin/firefox"
ser = Service("/tmp/geckodriver")
options = Options()
options.binary_location = "location for firefix bynary .. /firefox_binary.py"
options.headless = True
driver = webdriver.Firefox(options=options, service=ser)
Use the following code to go through Authentication. ( You need some selenium skills to code the manual process), I'll share the starting point as an example and you can code yours as it is different than the links that I am using.
import time
import re
import json
import requests
import pandas as pd
Options.binary_location = "/usr/bin/firefox"
ser = Service("/tmp/geckodriver")
options = Options()
options.headless = True
driver = webdriver.Firefox(options=options, service=ser)
tenant_id = 'your tenant id for Microsoft graph'
client_id = "your client id for Microsoft graph"
url = f"http://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize?client_id={client_id}&response_type=code&response_mode=query&scope=user.read%20chat.read&state=12345"
driver.get(url)
print(driver.current_url)
#open_tab
time.sleep(3)
This is the section that you are going to use your selenium skills, I just put the first step that is required by Microsoft, depending on your/your company setup you may need few more steps to sign in.
element_id = webdriver.common.by.By.ID
email_locator=(element_id,"i0116")
driver.find_element(*email_locator).send_keys("your email address")
next_button_locator = (element_id,"idSIButton9")
driver.find_element(*next_button_locator).click()
time.sleep(9)
print(driver.current_url)
I recommend printing driver.current_url after each steps so you can manually check the link and then code it accordingly.
After you logged in, now you can use the following code to get your Authentication token. I used localhost:5000 as return Url, but you can set up any URL that you want in your App registration page.
This authentication tokens are only valid for one hour, so I used the following while loop to refresh the token every 30 minutes
while True:
try:
driver.get(url)
except WebDriverException:
time.sleep(3)
url_pattern = 'http://localhost:5000/\?code=(?P<code>[^&]*)&state=12345.*'
re_match = re.match(url_pattern,driver.current_url)
code = re_match.group('code')
headers = { 'Content-Type': 'application/x-www-form-urlencoded'}
body = {'grant_type': 'authorization_code',
'code': code,
'redirect_url':'your redirect url',
'client_id': 'your client id',
'client_secret':'your client secret'}
response = requests.post('https://login.microsoftonline.com/yor tenant id/oauth2/v2.0/token',headers=headers,data = body)
access_token = json.loads(response.text)['access_token']
pd_response = pd.DataFrame([json.loads(response.text)])
# I am saving the new token in spark dataframe where I can read it with other code, but you can save it different way
sf_response = spark.createDataFrame(pd_response)
sf_response.write.mode("overwrite").saveAsTable('graphTest')
time.sleep(30*60)
Now if you got through all the obstacle that Microsoft throws at you to just authenticate yoursel, you can use the following line to post a message
#used this function to get updated token, but you can pass your token anyway that you want.
def getGraphAccessToken():
"""
Gets access token that is saved in graphTest table
"""
dataFrame = spark.sql("select * from graphTest")
return dataFrame.collect()[0]['access_token']
And Finally you can use the following codes to send the message to anyone or group of people as long as you have their chat id.
def sendIndividualChat(text,chatIdList,contentType="html"):
"""
sends individual chat through Microsoft Teams.
Parameters:
----------
text : str, message content
chatIdList : list, list of chat id(id is in string format) for individual chat messages
"""
headers = {'Content-type':'application/json',
"Authorization": f"Bearer {getGraphAccessToken()}"
}
body = {
"body": {
"contentType": contentType,
"content": text
}}
for chatId in chatIdList:
requests.post(f"https://graph.microsoft.com/v1.0/chats/{chatId}/messages",headers=headers,data =json.dumps(body) )
If you dont know how to get the chat id for the individuals or group chat there are few ways, you can use Graph Explorer https://developer.microsoft.com/en-us/graph/graph-explorer or the following code to get list of your most recent chat with their according chat id. Make sure you send the person/group that you want to get the chat id a message, so it shows up on recent chat messages.
def getCurrentChats():
"""
Gets list of current chats for current user.
Returns:
--------
Pandas DataFrame with information about the current chats
"""
headers = {'Content-type':'application/json',
"Authorization": f"Bearer {getGraphAccessToken()}"}
connection = http.client.HTTPSConnection("graph.microsoft.com")
connection.request("GET","/v1.0/me/chats",headers=headers)
resp = connection.getresponse()
text = resp.read()
return pd.DataFrame(json.loads(text)['value'])
def getCurrentChatMembers(currentChatsDataFrame,idColumn = 'id',debug=False):
"""
Get dictionary of member emails for each chat id
Parameters:
----------
currentChatsDataFrame : Pandas DataFrame returned from getCurrentChats()
idColumn : str, name of column with chat id (default= id)
Returns:
--------
Pandas DataFrame with ['memberName','memberEmail','chatId'] columns
"""
memberList = []
chatIdList = []
emailList = []
headers = {'Content-type':'application/json',
"Authorization": f"Bearer {getGraphAccessToken()}"}
connection = http.client.HTTPSConnection("graph.microsoft.com")
for chat_id in currentChatsDataFrame[idColumn]:
connection.request("GET",f"/v1.0/me/chats/{chat_id}/members",headers=headers)
resp = connection.getresponse()
text = resp.read()
#chatIdList.append(chat_id)
respJson = json.loads(text)['value']
dprint(respJson,debug=debug)
if respJson[1]['email'] =='your email address':# This returns the information about other chat member not the current user.
chatIdList.append(chat_id)
memberList.append(respJson[0]['displayName'])
emailList.append(respJson[0]['email'])
else:
chatIdList.append(chat_id)
memberList.append(respJson[1]['displayName'])
emailList.append(respJson[1]['email'])
dprint(text,debug=debug)
dprint('---------------------------')
#member_list.append(json.loads(text)['value'])
dprint(f"chatIdList is {chatIdList}",debug=debug)
dprint(f"memberlist is {memberList}",debug=debug)
dprint(f"emaillist is {emailList}",debug=debug)
return pd.DataFrame({'memberName':memberList,'memberEmail':emailList,'chatId': chatIdList})
Firstly :
Create a new channel in your Team if desired. A new channel will prevent Python generated notices from taking over other conversation channels.
img1
Add a new connector on your desired channel.
img 2
Find the Webhook connector and configure.
img 3
The configuration required is just a name for the webhook and optionally an image.
img4
img 5
Click create and copy the resulting webhook URL.
img6
Add this code your Python project so that it can write a message to Teams.
Install pymsteams with pip.
pip install pymsteams
Add this code to your Python project to enable writing messages to Teams, substitute the URL for your webhook:
import pymsteams
myTeamsMessage = pymsteams.connectorcard("INSERT WEBHOOK URL HERE")
Use this code to generate messages:
myTeamsMessage.text("This message was generated from Python!")
myTeamsMessage.send()
output
I have a list named linebline that contains around 99 lists within it (sublists). Within these sublists are dictionaries. I am interested in these dictionaries, as each sublist has a key named 'title' that I want a client/user to be able to query using a URL.
type(linebline) outputs list
type(linebline[0]) outputs dict
So far I have the following:
from flask import Flask, request, Response
app3 = Flask(__name__)
app3.route('/', methods = ['GET'])
def grab_title():
given_title = requests.args.get('title')
book_info = [obj for obj in linebline if obj['title'] == given_title] #.to_html(header="true", table_id="table")
return(book_info)
#return Response(city_inCom, mimetype = 'application/json')
app3.run(host = 'localhost', port = 5003)
An example of the query from a client would be:"http://localhost:5003/?title=New%20iPad%20Air%20may%20come%20with%20USB-C%20not%20Lightning%20Port%27"
I am currently getting:
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
I am not sure if I am addressing the 'title' key correctly OR am I not returning the right thing.
I'm currently writing a script to find emails based on the domain name using Hunter.io API
The thing is that my script returns me a JSON with a lot's a details and I only want the mail address in it.
Here's my code :
"""script to find emails based on the domain name using Hunter.io"""
import requests # To make get and post requests to APIs
import json # To deal with json responses to APIs
from pprint import pprint # To pretty print json info in a more readable format
from pyhunter import PyHunter # Using the hunter module
# Global variables
hunter_api_key = "API KEY" # API KEY
contacts = [] # list where we'll store our contacts
contact_info = {} # dictionary where we'll store each contact information
limit = 1 # Limit of emails adresses pulled by the request
value = "value" # <- seems to be the key in Hunter's API of the email adress founded
# TODO: Section A - Ask Hunter to find emails based on the domain name
def get_email_from_hunter(domain_name,limit):
url = "https://api.hunter.io/v2/domain-search"
params = {
"domain" : domain_name,
"limit" : 1,
"api_key" : hunter_api_key,
}
response = requests.get(url, params= params,)
json_data = response.json()
email_adress = json_data["data"]["emails"] # <- I have to find witch is the good key in order to return only the mail adress
#pprint(email_adress)
contact_info["email_adress"] = email_adress
contact_info["domain_name"] = domain_name
pprint(contact_info)
return contact_info
get_email_from_hunter("intercom.io","1")
and here's the JSON returned :
JSON exemple extracted from the documentation
Thanks per advance for the help provided :)
email_addresses = [item['value'] for item in json_data["data"]["emails"]]
note, not tested as you post image, not json data as text.
Good day.
I'm trying to get a list of all video files (links to direct downloading) from Vimeo account.
Is there a way to do it in a 1 GET request? OK, times to 100, if it is restriction of API.
I had hardcoded script, where I am making 12 GET request (1100+ videos, according to documentation, request is limited by 100 results), and then making over 1 000 requests to receive direct links.
Is there a way to to receive a list of links for downloading videous from Vimeo with one API request to server?
PS Account is PRO
import vimeo
import json
import config #token is here
client = vimeo.VimeoClient(
token = config.token
)
per_page = 100
answerDataAll = []
for i in range(12):
page=i+1
getString = 'https://api.vimeo.com/me/videos?per_page='+str(per_page) + '&page=' + str(page)
dataFromServer = client.get(getString).json()['data']
answerDataAll.extend(dataFromServer)
# creating list of videos
listOfItems = []
for item in answerDataAll:
listOfItems.append( item ['uri'])
# creating list of direct links, it is the goal
listOfUrls = []
for item in listOfItems:
# isolating digits
videoID = ""
for sign in item:
if sign.isdigit():
videoID = videoID + sign
requestForDownloading = client.get ('http://player.vimeo.com/video/' + videoID + '/config').json()['request']['files']['progressive']
for itm in requestForDownloading:
if itm['width']==640:
urlForDownloading = itm['url']
listOfUrls.append(urlForDownloading)
You can get up to 100 videos per request, but understand that a request like that to /me/videos will return the full metadata for each video, which is a lot of data to parse through. The API or your client may also timeout while Vimeo's servers try to render your request.
You should use the fields parameter so that only the download metadata you need is returned. You should also specify the sort and direction, so you know exactly order the videos should be returning in. The request uri should be formatted like this:
https://api.vimeo.com/me/videos?fields=uri,name,download&page=1&per_page=100&sort=date&direction=desc
Documentation of those parameters is found here:
https://developer.vimeo.com/api/common-formats#json-filter
https://developer.vimeo.com/api/common-formats#using-the-pagination-parameter
https://developer.vimeo.com/api/common-formats#using-the-sort-parameters
Basically i need to get all messages of a page using facebook SDK in python.
Following some tutorial i arrived to this point:
import facebook
def main():
cfg = {
"page_id" : "MY PAGE ID",
"access_token" : "LONG LIVE ACCESS TOKEN"
}
api = get_api(cfg)
msg = "Hre"
status = api.put_wall_post(msg) #used to post to wall message Hre
x = api.get_object('/'+str(MY PAGE ID)+"/conversations/") #Give actual conversations
def get_api(cfg):
graph = facebook.GraphAPI(cfg['access_token'])
resp = graph.get_object('me/accounts')
page_access_token = None
for page in resp['data']:
if page['id'] == cfg['page_id']:
page_access_token = page['access_token']
graph = facebook.GraphAPI(page_access_token)
return graph
if __name__ == "__main__":
main()
The first problem is that api.get_object('/'+str(MY PAGE ID)+"/conversations/")returns a dictionary containing many informations, but what i would like to see is the messages they sent to me, while for now it print the user id that sent to me a message.
The output look like the following:
{u'paging': {u'next': u'https://graph.facebook.com/v2.4/571499452991432/conversations?access_token=Token&limit=25&until=1441825848&__paging_token=enc_AdCqaKAP3e1NU9MGSsvSdzDPIIDtB2ZCe2hCYfk7ft5ZAjRhsuVEL7eFYOOCdQ8okvuhZA5iQWaYZBBbrZCRNW8uzWmgnKGl69KKt4catxZAvQYCus7gZDZD', u'previous': u'https://graph.facebook.com/v2.4/571499452991432/conversations?access_token=token&limit=25&since=1441825848&__paging_token=enc_AdCqaKAP3e1NU9MGSsvSdzDPIIDtB2ZCe2hCYfk7ft5ZAjRhsuVEL7eFYOOCdQ8okvuhZA5iQWaYZBBbrZCRNW8uzWmgnKGl69KKt4catxZAvQYCus7gZDZD&__previous=1'}, u'data': [{u'link': u'/communityticino/manager/messages/?mercurythreadid=user%3A1055476438&threadid=mid.1441825847634%3Af2e0247f54f5c4d222&folder=inbox', u'id': u't_mid.1441825847634:f2e0247f54f5c4d222', u'updated_time': u'2015-09-09T19:10:48+0000'}]}
which is basically paging and data.
Given this is there a way to read the conversation?
In order to get the messages content you need first to request the single messages in the conversation, accessible with the 'id' field in the dictionary you copied, result of
x = api.get_object('/'+str(MY PAGE ID)+"/conversations/") #Give actual conversations
you can request the messages in the conversation by calling
msg = api.get_object('/'+<message id>)
Here it gets tricky, because following the graph api documentation you should receive back a dictionary with ALL the possible fields, including the 'message' (content) field. The function however returns only the fields 'created_time' and 'id'.
Thanks to this other question Request fields in Python Facebook SDK I found that you can request for those fields by adding a dict with such fields specified in the arguments of the graph.get_object() function. As far as I know this is undocumented in the facebook sdk reference for python.
The correct code is
args = {'fields' : 'message'}
msg = api.get_object('/'+<message id>, **args)
Similar question: Read facebook messages using python sdk