I'm trying to upload some files (multiple files and folder) to sharepoint and when I run the script i dont have any errors but i'm unable so see my files in sharepoint.
import requests
from shareplum import Office365
# get data from configuration
username = 'last.surname#tenant.com'
password = 'mypassword'
site_name = 'BI_odair'
base_path = 'https://tenant.sharepoint.com'
doc_library = 'data'
file_name = "links.txt"
# Obtain auth cookie
authcookie = Office365(base_path, username=username,
password=password).GetCookies()
session = requests.Session()
session.cookies = authcookie
session.headers.update({'user-agent': 'python_bite/v1'})
session.headers.update({'accept': 'application/json;odata=verbose'})
# perform the actual upload
with open(file_name, 'rb') as file_input:
try:
response = session.post(
url=base_path + "/sites/" + site_name +
"/_api/web/GetFolderByServerRelativeUrl('Shared%20Documents/" +
doc_library+"')/Files/add(url='"
+ file_name + "',overwrite=true)",
data=file_input)
except Exception as err:
print("Some error occurred: " + str(err))
URL for my sharepoint: https://tenant.sharepoint.com/sites/BI_odair/Documents%20partages/Forms/AllItems.aspx?viewid=4e7fdfb9%2De84a%2D42cd%2Db537%2D0d2837ca92cc
Theres already a folder named Data, but i wanted to upload my files in the root folder "/Documents%20partages"
I've already added this to my code: https://stackoverflow.com/a/59083429/6754555
Thanks in advance.
Here's the solution that worked perfectly on my end:
pip install SharePlum and then use the code below
import requests
from shareplum import Office365
# Set Login Info
username = '<username>'
password = '<password>'
site_name = '<site_name>'
base_path = 'https://<domain_name>.sharepoint.com'
doc_library = 'Shared%20Documents'
nested_folder = 'Shared%20Documents/<folder1>/<folder2>' #if you want to upload in nested folders else nested_folder = doc_library
file_name = "my_file.zip" #when your file in the same directory
# Obtain auth cookie
authcookie = Office365(base_path, username=username, password=password).GetCookies()
session = requests.Session()
session.cookies = authcookie
session.headers.update({'user-agent': 'python_bite/v1'})
session.headers.update({'accept': 'application/json;odata=verbose'})
session.headers.update({'X-RequestDigest': 'FormDigestValue'})
response = session.post(url=base_path + "/sites/" + site_name + "/_api/web/GetFolderByServerRelativeUrl('" + doc_library + "')/Files/add(url='a.txt',overwrite=true)",
data="")
session.headers.update({'X-RequestDigest': response.headers['X-RequestDigest']})
# perform the actual upload
with open(file_name, 'rb') as file_input:
try:
response = session.post(
url=base_path + "/sites/" + site_name + f"/_api/web/GetFolderByServerRelativeUrl('" + nested_folder + "')/Files/add(url='"
+ file_name + "',overwrite=true)",
data=file_input)
print("response: ", response.status_code) #it returns 200
if response.status_code == '200':
print("File uploaded successfully")
except Exception as err:
print("Something went wrong: " + str(err))
print('File Uploaded Successfully')
"Shared Documents" is the default document library. If you want to upload file to a custom library, please modify the path as below:
response = session.post(
url=base_path + "/sites/" + site_name +
"/_api/web/GetFolderByServerRelativeUrl("Documents%20partages")/Files/add(url='"
+ file_name + "',overwrite=true)",
data=file_input)
Also you can have a look at below blog:Uploading files to SharePoint
//////// Updated
I created a document library and tested the demo in above blog, it works well.
Below is my code:
import requests
from shareplum import Office365
from config import config
# get data from configuration
username = config['sp_user']
password = config['sp_password']
site_name = config['sp_site_name']
base_path = config['sp_base_path']
doc_library = config['sp_doc_library']
file_name = "test.csv"
# Obtain auth cookie
authcookie = Office365(base_path, username=username, password=password).GetCookies()
session = requests.Session()
session.cookies = authcookie
session.headers.update({'user-agent': 'python_bite/v1'})
session.headers.update({'accept': 'application/json;odata=verbose'})
# dirty workaround.... I'm getting the X-RequestDigest from the first failed call
session.headers.update({'X-RequestDigest': 'FormDigestValue'})
response = session.post( url=base_path + "/sites/" + site_name + "/_api/web/GetFolderByServerRelativeUrl('" + doc_library + "')/Files/add(url='a.txt',overwrite=true)",
data="")
session.headers.update({'X-RequestDigest': response.headers['X-RequestDigest']})
# perform the actual upload
with open( r'C:\Users\xxx\Documents\test.csv', 'rb+') as file_input:
try:
response = session.post(
url=base_path + "/sites/" + site_name + "/_api/web/GetFolderByServerRelativeUrl('" + doc_library + "')/Files/add(url='"
+ file_name + "',overwrite=true)",
data=file_input)
except Exception as err:
print("Some error occurred: " + str(err))
print('end...')
Related
I'm trying to upload image from url to wordpress without saving it in my device using python and rest api , i'm really close to achive that i just can't find where i'm lost
i keep getting 500 and this error :
{"code":"rest_upload_unknown_error","message":"Sorry, you are not allowed to upload this file type.","data":{"status":500}}
my code :
import base64, requests
def header(user, password):
credentials = user + ':' + password
token = base64.b64encode(credentials.encode())
header_json = {'Authorization': 'Basic ' + token.decode('utf-8'),
'Content-Disposition' : 'attachment; filename=%s'% "test1.jpg"}
return header_json
def upload_image_to_wordpress(file_path, header_json):
media = {'file': file_path,'caption': 'My great demo picture'}
responce = requests.post("https://website.com/wp-json/wp/v2/media", headers = header_json, files = media)
print(responce.text)
heder = header("user","password") #username, application password
url = "https://cdn.pixabay.com/photo/2021/11/30/08/24/strawberries-6834750_1280.jpg"
raw = requests.get(url).content
upload_image_to_wordpress(raw,heder)
after trying many solutions i found out working one
from tempfile import NamedTemporaryFile
url = "https://cdn.pixabay.com/photo/2021/11/30/08/24/strawberries-6834750_1280.jpg"
raw = requests.get(url).content
with NamedTemporaryFile(delete=False,mode="wb",suffix=".jpg") as img :
img.write(raw)
# print(f.file())
c = open(img.name,"rb")
upload_image_to_wordpress(c,heder)
I am trying to achieve this through a Python program. I am able to pull logs from API to a local drive.
However I am struggling to copy them to AWS S3. I appreciate your help on this.
I am using the code below to copy files to a local drive
''''''
import requests
import requests.auth
from bs4 import BeautifulSoup
import os.path
from pathlib import Path
import os
import boto3
CLIENT_ID = "xxxxxxxx"
CLIENT_SECRET = "xxxxxxxx"
TOKEN_URL = "https://xxxxxxxx/dwsso/oauth2/access_token"
REDIRECT_URI = "https://xxxxxxxx/dwsso/oauth2/callback"
def get_token(code=None):
client_auth = requests.auth.HTTPBasicAuth(CLIENT_ID, CLIENT_SECRET)
post_data = {"grant_type": "client_credentials",
"code": code,
"redirect_uri": REDIRECT_URI}
response = requests.post(TOKEN_URL,
auth=client_auth,
data=post_data)
token_json = response.json()
return token_json["access_token"]
my_token=get_token()
headersAPI = {
'accept': 'application/json',
'Authorization': 'Bearer '+ my_token,
}
params = (
('offset', '0'),
('limit', '20'),
)
def download_files(urls):
for a in soup.find_all('a', href=True):
url = urls
a = a['href']
logs_url = url + a
r = requests.get(logs_url, headers=headersAPI, params=params, verify=True, stream = True)
save_path = "download" + ((url.split('/')[2]).split('.')[0])
Path(save_path).mkdir(parents=True, exist_ok=True)
lname = (logs_url.split('/')[-1])
completeName= os.path.join(save_path, lname)
print("Downloding file from %s domain: %s" % ( save_path, lname )
open(completeName, 'wb').write(r.content)
url_lst = [ "https://xxxxxxxx/webdav/Sites/Logs/",
"https://xxxxxxxx/webdav/Sites/Logs/",
"https://xxxxxxxx/Sites/Logs/" ]
for i in url_lst:
response = requests.get(myUrl, headers=headersAPI, params=params, verify=True, stream = True)
soup = BeautifulSoup(response.content, 'html.parser')
f_url = ((i.split('/')[2]))
url = "https://" + f_url
download_files(url)
''''''
You can upload to S3 buckets using Boto3:
import boto3
s3 = boto3.resource('s3')
s3.Bucket('mybucket').upload_file('/tmp/hello.txt', 'hello.txt')
See Upload to S3 Bucket documentation here.
And here for installation and config of Boto3.
Working example to generate a valid url (including signature) for the Huobi API.
In the Huobi API documenation there is no explicit example that allows you to verify your signature creation method step by step.
My intention is to create that here, but I need help, because I haven't managed yet.
The following is supposed to be the recipe.
Note that once you have this working, substitute valid values for your API key + secret and timestamp:
import hmac
import hashlib
import base64
from urllib.parse import urlencode
API_KEY = 'dummy-key'
API_SECRET = 'dummy-secret'
timestamp = '2021-03-04T11:36:39'
params_dict = {
'AccessKeyId': API_KEY,
'SignatureMethod': 'HmacSHA256',
'SignatureVersion': '2',
'Timestamp': timestamp
}
params_url_enc = urlencode(sorted(params_dict.items()))
pre_signed = 'GET\n'
pre_signed += 'api.huobi.pro\n'
pre_signed += '/v1/account/accounts\n'
pre_signed += params_url_enc
sig_bytes = hmac.new(
API_SECRET.encode(),
pre_signed.encode(),
hashlib.sha256).hexdigest().encode()
sig_b64_bytes = base64.b64encode(sig_bytes)
sig_b64_str = sig_b64_bytes.decode()
sig_url = urlencode({'Signature': sig_b64_str})
url = 'https://api.huobi.pro/v1/account/accounts?'
url += params_url_enc + '&'
url += sig_url
print('API_KEY={}'.format(API_KEY))
print('API_SECRET={}'.format(API_SECRET))
print('timestamp={}'.format(timestamp))
print('params_dict={}'.format(params_dict))
print('params_url_enc={}'.format(params_url_enc))
print('pre_signed:\n{}'.format(pre_signed))
print('sig_bytes={}'.format(sig_bytes))
print('sig_b64_bytes={}'.format(sig_b64_bytes))
print('sig_b64_str={}'.format(sig_b64_str))
print('sig_url={}'.format(sig_url))
print('url={}'.format(url))
Gives:
API_KEY=dummy-key
API_SECRET=dummy-secret
timestamp=2021-03-04T11:36:39
params_dict={'AccessKeyId': 'dummy-key', 'SignatureMethod': 'HmacSHA256', 'SignatureVersion': '2', 'Timestamp': '2021-03-04T11:36:39'}
params_url_enc=AccessKeyId=dummy-key&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2021-03-04T11%3A36%3A39
pre_signed:
GET
api.huobi.pro
/v1/account/accounts
AccessKeyId=dummy-key&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2021-03-04T11%3A36%3A39
sig_bytes=b'1921de9f42284bc0449c5580f52a9f7e7e3a54a6e8befc0d320992e757517a6b'
sig_b64_bytes=b'MTkyMWRlOWY0MjI4NGJjMDQ0OWM1NTgwZjUyYTlmN2U3ZTNhNTRhNmU4YmVmYzBkMzIwOTkyZTc1NzUxN2E2Yg=='
sig_b64_str=MTkyMWRlOWY0MjI4NGJjMDQ0OWM1NTgwZjUyYTlmN2U3ZTNhNTRhNmU4YmVmYzBkMzIwOTkyZTc1NzUxN2E2Yg==
sig_url=Signature=MTkyMWRlOWY0MjI4NGJjMDQ0OWM1NTgwZjUyYTlmN2U3ZTNhNTRhNmU4YmVmYzBkMzIwOTkyZTc1NzUxN2E2Yg%3D%3D
url=https://api.huobi.pro/v1/account/accounts?AccessKeyId=dummy-key&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2021-03-04T11%3A36%3A39&Signature=MTkyMWRlOWY0MjI4NGJjMDQ0OWM1NTgwZjUyYTlmN2U3ZTNhNTRhNmU4YmVmYzBkMzIwOTkyZTc1NzUxN2E2Yg%3D%3D
Also add header in sending:
{"Content-Type": "application/x-www-form-urlencoded"}
Unfortunately, when I substitute my own valid API key + secret and a proper UTC time stamp, I invariably receive:
{"status":"error","err-code":"api-signature-not-valid","err-msg":"Signature not valid: Verification failure [校验失败]","data":null}
So what is going wrong here?
Huobi API documentation is
https://huobiapi.github.io/docs/spot/v1/en/#introduction
To get all accounts, use endpoint GET /v1/account/accounts
from datetime import datetime
import requests
import json
import hmac
import hashlib
import base64
from urllib.parse import urlencode
#Get all Accounts of the Current User
AccessKeyId = 'xxxxx-xxxxx-xxxxx-xxxxx'
SecretKey = 'xxxxx-xxxxx-xxxxx-xxxxx'
timestamp = str(datetime.utcnow().isoformat())[0:19]
params = urlencode({'AccessKeyId': AccessKeyId,
'SignatureMethod': 'HmacSHA256',
'SignatureVersion': '2',
'Timestamp': timestamp
})
method = 'GET'
endpoint = '/v1/account/accounts'
base_uri = 'api.huobi.pro'
pre_signed_text = method + '\n' + base_uri + '\n' + endpoint + '\n' + params
hash_code = hmac.new(SecretKey.encode(), pre_signed_text.encode(), hashlib.sha256).digest()
signature = urlencode({'Signature': base64.b64encode(hash_code).decode()})
url = 'https://' + base_uri + endpoint + '?' + params + '&' + signature
response = requests.request(method, url)
accts = json.loads(response.text)
print(accts)
Subsequently, if you need to run another endpoint (note timestamp allowance is ±5 minutes),
example, to get account balance, use GET /v1/account/accounts/{account_id}/balance
#Get Account Balance of a Specific Account
account_id = accts['data'][0]['id']
method = 'GET'
endpoint = '/v1/account/accounts/{}/balance'.format(account_id)
pre_signed_text = method + '\n' + base_uri + '\n' + endpoint + '\n' + params
hash_code = hmac.new(SecretKey.encode(), pre_signed_text.encode(), hashlib.sha256).digest()
signature = urlencode({'Signature': base64.b64encode(hash_code).decode()})
url = 'https://' + base_uri + endpoint + '?' + params + '&' + signature
response = requests.request(method, url)
r = json.loads(response.text)
print(r)
The mistake was that I took the hexidigest of the hash, whereas the digest was needed.
Working recipe here that you can check numerically to validate your code:
import hmac
import hashlib
import base64
from urllib.parse import urlencode
API_KEY = 'dummy-key'
API_SECRET = 'dummy-secret'
timestamp = '2021-03-04T12:54:56'
params_dict = {
'AccessKeyId': API_KEY,
'SignatureMethod': 'HmacSHA256',
'SignatureVersion': '2',
'Timestamp': timestamp
}
params_url_enc = urlencode(
sorted(params_dict.items(), key=lambda tup: tup[0]))
pre_signed = 'GET\n'
pre_signed += 'api.huobi.pro\n'
pre_signed += '/v1/account/accounts\n'
pre_signed += params_url_enc
sig_bin = hmac.new(
API_SECRET.encode(),
pre_signed.encode(),
hashlib.sha256).digest()
sig_b64_bytes = base64.b64encode(sig_bin)
sig_b64_str = sig_b64_bytes.decode()
sig_url = urlencode({'Signature': sig_b64_str})
url = 'https://api.huobi.pro/v1/account/accounts?'
url += params_url_enc + '&'
url += sig_url
print('API_KEY={}'.format(API_KEY))
print('API_SECRET={}'.format(API_SECRET))
print('timestamp={}'.format(timestamp))
print('params_dict={}'.format(params_dict))
print('params_url_enc={}'.format(params_url_enc))
print('pre_signed:\n{}'.format(pre_signed))
print('sig_bin={}'.format(sig_bin))
print('sig_b64_bytes={}'.format(sig_b64_bytes))
print('sig_b64_str={}'.format(sig_b64_str))
print('sig_url={}'.format(sig_url))
print('url={}'.format(url))
Result:
$ python test_huobi_so.py
API_KEY=dummy-key
API_SECRET=dummy-secret
timestamp=2021-03-04T12:54:56
params_dict={'AccessKeyId': 'dummy-key', 'SignatureMethod': 'HmacSHA256', 'SignatureVersion': '2', 'Timestamp': '2021-03-04T12:54:56'}
params_url_enc=AccessKeyId=dummy-key&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2021-03-04T12%3A54%3A56
pre_signed:
GET
api.huobi.pro
/v1/account/accounts
AccessKeyId=dummy-key&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2021-03-04T12%3A54%3A56
sig_bin=b'_\xb9k\x82!\xb4B%A\xfe\x0c \xff\x07%JE\xbe\x82\x8b-<^\xb7\xfc\x06\x85G\xb5$\x81\xd7'
sig_b64_bytes=b'X7lrgiG0QiVB/gwg/wclSkW+gostPF63/AaFR7Ukgdc='
sig_b64_str=X7lrgiG0QiVB/gwg/wclSkW+gostPF63/AaFR7Ukgdc=
sig_url=Signature=X7lrgiG0QiVB%2Fgwg%2FwclSkW%2BgostPF63%2FAaFR7Ukgdc%3D
url=https://api.huobi.pro/v1/account/accounts?AccessKeyId=dummy-key&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2021-03-04T12%3A54%3A56&Signature=X7lrgiG0QiVB%2Fgwg%2FwclSkW%2BgostPF63%2FAaFR7Ukgdc%3D
Hi I am new to python and REST API,
I am getting 415 error while trying to run a query in cms using requests.post
I am not able to pass content-type and Accept along with the logon token.
I am able to run this in talend along with these 2 headers.
Can you please help me in how to add these 2 headers in requests.post at the end.
Below is my code
import requests
from lxml import etree
import xml.etree.ElementTree as ET
import pandas as pd
import openpyxl as x
from bs4 import BeautifulSoup
import xmltodict
protocol='http'
host='HOST'
port='6405'
content_type='application/xml'
base_url = protocol + '://' + host + ':' + port
bip_url = base_url + '/biprws'
webi_url = bip_url + '/raylight/v1'
sl_url = bip_url + '/sl/v1'
headers_auth = {
'Content-Type' : content_type,'Accept':'application/xml'
}
headers = {
}
username = 'user'
password = 'pass'
auth = requests.get(bip_url + '/logon/long', headers=headers)
root = etree.fromstring(auth.text)
root[3].text = username
root[0].text = password
etree.tostring(root)
send = requests.post(bip_url + '/logon/long',
headers=headers_auth,
data=etree.tostring(root))
tokenresp = etree.fromstring(send.content)
headers['X-SAP-LogonToken'] = tokenresp[3][0][0].text
folder_get = requests.get(bip_url + '/v1/cmsquery', headers=headers)
folder_root = etree.fromstring(folder_get.text)
Query_var = 'SELECT SI_ID,SI_NAME FROM CI_INFOOBJECTS WHERE SI_ANCESTOR = 12141'
folder_root[0].text = Query_var
data1 = etree.tostring(folder_root)
folder_post = requests.post(bip_url + '/v1/cmsquery', headers = headers, data = data1)
folder_post.status_code
I think 415 means that you're passing a content type that the API doesn't accept. You need to configure your headers correctly. Try this:
headers = {
'Content-Type' : 'application/xml'
}
auth = requests.get(bip_url + 'logon/long', headers=headers)
print(auth.status_code)
It looks like your problem is that you set headers to a blank dictionary.
I have a function to upload a file through rest API which uses token for authorization which expires in 30 minutes. When I upload a big file I get timeout and the code breaks. The token grant_type=password and the response does not include refresh token. Can someone help me with it. Below is the function.
def post_Return_File(url, token, uploadFile):
import requests
from os.path import splitext
#post urls ----change here
head = {'Authorization':'Bearer ' + token}
files_to_upload = []
file_num = 0
for files in uploadFile:
file_num = file_num + 1
fileName = 'file' + str(file_num)
filepath = (fileName,(files, open(files,'rb'), (splitext(files)[-1]).strip('.')))
files_to_upload.append(filepath)
#sending the request for response
post_res = requests.post(url, headers = head, files = files_to_upload)
if (post_res.status_code == 200):
post_response = post_res.status_code
return post_response
else:
post_err = post_res.status_code
return post_err