(adsbygoogle = window.adsbygoogle || []).push({});
cause
Because I bought an E5 5T for nothing before, I was really blind if I didn’t want to make a network disk, but because oneindex has been in disrepair for a long time, I finally chose SpencerWoo’s onedrive-vercel-index , but because it is hosted on vercel, there is no way to upload files like oneindex, which makes me very annoyed, so I combined online tutorials and Microsoft's Azure Active Directory Documentation I wrote a small example based on onedrive for business.
Development Process
- Client ID and secret (client secret) registered with Azure Active Directory (AAD)
- Authorization code received from OAuth 2 authorization code flow
- OneDrive for Business API endpoint URL
- Access tokens for OneDrive for Business resources
- Generates refresh tokens for additional access tokens when the current token expires.
start docking
Friends who have used oneindex for client id and key should know how to set it up, so I won’t introduce it here. In addition, just set a callback uri. I use “localhost:8400”
get access_token
onedrive for business uses the standard Oauth2 process, so the general process is to obtain the code first, use the code to exchange the access_token, and then call the api, here first post the code for obtaining the code and exchanging the access_token:
copydef get_token(self, url): code = parse_qs(urlparse(url).query).get('code')[0] data = { 'client_id': self.client_id, 'redirect_uri': self.redirect_uri, 'client_secret': self.client_secret, 'code': code, 'grant_type': 'authorization_code', 'resource': self.resource_uri } resp = requests.post(self.oauth2_uri, headers=self.header, data=data).json() return self.save_token(resp) def refresh_token(self): token = self.read_token(only_read=True) data = { 'client_id': self.client_id, 'redirect_uri': self.redirect_uri, 'client_secret': self.client_secret, 'refresh_token': token['refresh_token'], 'grant_type': 'refresh_token', 'resource': 'https://graph.microsoft.com' } resp = requests.post(self.oauth2_uri, headers=self.header, data=data).json() return self.save_token(resp)
onedrive upload files
After obtaining the token, you can call the code related to onedrive for business. Since a file larger than 4MB needs to create a session to upload in pieces, so here I wrote two upload methods. The approximate code is as follows:
copydef get_path(self, path, op): if path[0] == '/': path = path[1:] if path[-1] == '/': path = path[:-1] if op[0] == '/': op = op[1:] return self.onedrive_uri + '/root:/backup/{}:/{}'.format(path, op) def create_folder(self, path): path = list(filter(None, path.split('/'))) pa = '/'.join(path[:len(path) - 1]) name = path[len(path) - 1] data = json.dumps({ "name": name, "folder": {}, }) r = requests.post(self.get_path(pa, 'children'), headers=self.header, data=data) return r.status_code def upload_url(self, path, conflict="fail"): r = requests.post(self.get_path( path, 'createUploadSession' ), headers=self.header) if r.status_code == 200: return r.json()['uploadUrl'] else: return "" def upload_file(self, path, data): size = len(data) if size > 4000000: return self.upload_big_file(path, data) else: r = requests.put(self.get_path(path, 'content'), headers=self.header, data=data) if 'error' in r: return "upload failed" return "uploaded successfully" def upload_big_file(self, path, data): url = self.upload_url(path) if url == "": return "upload cancel" size = len(data) chunk_size = 3276800 file_name = path.split('/')[len(path.split('/')) - 1] pbar = tqdm(total=size, leave=False, unit='B', unit_scale=True, desc=file_name) for i in range(0, size, chunk_size): chunk_data = data[i:i + chunk_size] pbar.update(len(chunk_data)) r = requests.put(url, headers={ 'Content-Length': str(len(chunk_data)), 'Content-Range': 'bytes {}-{}/{}'.format(i, i + len(chunk_data) - 1, size) }, data=chunk_data) if r.status_code not in [200, 201, 202]: print("upload error") break
A few pits encountered
- The endpoint is https://graph.microsoft.com
- The request api of onedrive is https://graph.microsoft.com/v1.0/me/drive, but the documentation and online tutorials write https://graph.microsoft.com/me/drive, which is what I think a little pitiful
- secret needs to copy "value", not "secret ID"
full code
The content here needs to be read after commenting and replying
use case
1. Configure self.client_id and self.client_secret 2. Introduce one in other files, or introduce onedrive to instantiate it yourself
copyfrom onedrive import one
3. Upload files
copyif __name__ == '__main__': # Upload path to onedirve remote = '/uploads/images/logo.png' # local file path file = os.getcwd()+'/images/logo.png' with open(file, 'rb') as f: # Small files will print "uploaded successfully", and large files will display an upload progress bar print(one.upload_file(remote, f.read()))
Unless otherwise specified "onedrive for business uses python to upload files" Originally created by the blogger MoLeft, please indicate the original text link as: https://moleft.cn/post-276.html