Coder Social home page Coder Social logo

pcloud's Introduction

pcloud - A Python API client for pCloud

This Python (Version >= 3.6 only!) library provides a Python API to the pCloud storage.

Features

  • Can be used as a library
  • Provides a PyFileSystem implementation

Examples

Usage of API

>>> from pcloud import PyCloud
>>> pc = PyCloud('[email protected]', 'SecretPassword')
>>> pc.listfolder(folderid=0)

Use alternate endpoints (API calls have to be made to the correct API host name depending were the user has been registered – api.pcloud.com for United States and eapi.pcloud.com for Europe.)

>>> from pcloud import PyCloud
>>> pc = PyCloud('[email protected]', 'SecretPassword', endpoint="eapi")
>>> pc.listfolder(folderid=0)

PyCloud also provides an API method to retrieve the nearest API server, which gives you a speed gain for some API operations. To use PyCloud with this feature create the PyCloud-object with the nearest endpoint parameter:

>>> from pcloud import PyCloud
>>> pc = PyCloud('[email protected]', 'SecretPassword', endpoint="nearest")
>>> pc.listfolder(folderid=0)

OAuth 2.0 authentication

To use OAuth 2.0 authentication you need to create an App in pCloud (https://docs.pcloud.com/my_apps/).

Add the following redirect URI http://localhost:65432/ (Make sure port 65432 is available on your machine. Otherwise you need to adjust the PORT in oauth2.py)

Note! To see the redirect URI in the settings of pCloud you have to log out and log in again.

Once you finished adding the app and setting the redirect URI you are ready to use OAuth 2.0 with PyCloud on your machine. For the communication with pCloud PyCloud uses the builtin webserver-module. This means you need a real browser on your system available.

>>> from pcloud import PyCloud
>>> pc = PyCloud.oauth2_authorize(client_id="XYZ", client_secret="abc123")
>>> pc.listfolder(folderid=0)

Headless mode

OAuth 2.0 is designed to use a browser for the authentication flow. Nevertheless Selenium can be used to automate this process. For an example see the pycloud_oauth2-fixture in test_oauth2.py. This method will not integrated as main functionality, since there are too many dependencies. You can use it as example for your usecase.

Uploading files

  1. from filenames:
>>> pc.uploadfile(files=['/full/path/to/image1.jpg', '/Users/tom/another/image.png'],
...     path='/path-to-pcloud-dir')
  1. from data:
>>> import io
>>> from PIL import Image
>>> img = Image.open('image.jpg', 'r')
>>> bio = io.BytesIO()
>>> img.save(bio, format='jpeg')
>>> pc.uploadfile(data=bio.getvalue(), filename="image.jpg", path='/path-to-pcloud-dir')

Usage of PyFilesystem with opener

>>> from fs import opener
>>> opener.open_fs('pcloud://email%40example.com:SecretPassword@/')
<pCloudFS>

Copying files from Linux to pCloud using PyFilesystem

>>> from fs import opener, copy
>>> with opener.open_fs('pcloud://email%40example.com:SecretPassword@/') as pcloud_fs:
>>>    with opener.open_fs('/opt/data_to_copy') as linux_fs:
>>>        copy.copy_file(src_fs=linux_fs,
>>>                       src_path='database.sqlite3',
>>>                       dst_fs=pcloud_fs,
>>>                       dst_path='/backup/server/database.sqlite3')

Copy directory from Linux to pCloud using PyFilesystem

>>> from fs import opener, copy
>>> with opener.open_fs('pcloud://email%40example.com:SecretPassword@/') as pcloud_fs:
>>>    with opener.open_fs('/opt/data_to_copy') as linux_fs:
>>>        copy.copy_dir(src_fs=linux_fs,
>>>                      src_path='database/',
>>>                      dst_fs=pcloud_fs,
>>>                      dst_path='/backup/database/')

Further Documentation

Implements the pCloud API found at https://docs.pcloud.com/

Installation

$ pip install pcloud

Installation with PyFilesystem support

$ bin/pip install pcloud[pyfs]

on zsh (Mac):

$ bin/pip install "pcloud[pyfs]"

Development

For testing purposes a mock server is provided. To use this mock server you need to add a file with the same name as the method + the .json suffix in the tests/data directory (like getdigest.json). The file contains the expected JSON result.

Contribute

License

The project is licensed under MIT (see LICENSE).

pcloud's People

Contributors

blasterspike avatar giust avatar jaetma avatar masrlinu avatar olokelo avatar snyk-bot avatar tomgross avatar yennicks avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pcloud's Issues

Implement "use near api server"

pCloud has an API method to get the nearest API server, which gives some speed enhancements when used.

PyCloud could provide a flag to enable this feature.

Need help on file download from Pcloud to Local Directory.

I have uploaded a file to Pcloud. But this time, there is a requirement to download the uploaded file or download the already existing file from cloud. But I am unable to do so. So I have added the code snippet. Can you please provide a solution for it?

Code Snippet:

pc = PyCloud('email id', 'password', endpoint='eapi')

listr = pc.listfolder(folderid=0)

pc.downloadfile(url="File Download Link", path="Local Directory")

I can pay you for the solution.

FEATURE: Have ability to run pcloud on headless server/terminal

Tried pcloud using oauth, which works fine, but then the API is looking for a firefox browser or similar on a desktop/GUI. The script should be able to run within console/terminal (headless server). See output below:

$ python          
Python 3.9.6 (default, Jul  6 2021, 19:38:26)                                                     
[GCC 10.2.0] on linux                           
Type "help", "copyright", "credits" or "license" for more information.
>>> from pcloud import PyCloud
>>> pc = api.PyCloud.oauth2_authorize(client_id="MY_CID", client_secret="MY_CS")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'api' is not defined
>>> from pcloud import api                                                                         
>>> pc = api.PyCloud.oauth2_authorize(client_id="MY_CID", client_secret="MY_CS")
/usr/bin/xdg-open: line 881: x-www-browser: command not found
/usr/bin/xdg-open: line 881: firefox: command not found
/usr/bin/xdg-open: line 881: iceweasel: command not found
/usr/bin/xdg-open: line 881: seamonkey: command not found
/usr/bin/xdg-open: line 881: mozilla: command not found
/usr/bin/xdg-open: line 881: epiphany: command not found
/usr/bin/xdg-open: line 881: konqueror: command not found
/usr/bin/xdg-open: line 881: chromium: command not found
/usr/bin/xdg-open: line 881: chromium-browser: command not found
/usr/bin/xdg-open: line 881: google-chrome: command not found
/usr/bin/xdg-open: line 881: www-browser: command not found
/usr/bin/xdg-open: line 881: links2: command not found
/usr/bin/xdg-open: line 881: elinks: command not found
/usr/bin/xdg-open: line 881: links: command not found
/usr/bin/xdg-open: line 881: lynx: command not found
/usr/bin/xdg-open: line 881: w3m: command not found
xdg-open: no method available for opening 'https://my.pcloud.com/oauth2/authorize?response_type=code&redirect_uri=http://localhost:65432/&client_id=MY_CID'

Is there any upload limit?

while uploading a file of size 2.65 GB using python I get this error

/usr/lib/python3.6/ssl.py in write(self, data)
    640         The 'data' argument must support the buffer interface.
    641         """
--> 642         return self._sslobj.write(data)
    643 
    644     def getpeercert(self, binary_form=False):

OverflowError: string longer than 2147483647 bytes

How can i solve this problem? please help...

Saving the auth code token between oauth2 calls.

In testing it seems like each time one uses oauth2 e.g.

pc = PyCloud.oauth2_authorize(client_id=api_id, client_secret=api_secret)

There's a redirect and one has to login each time. E.g. the auth_token does not seem to get reused.
I see it is printed out:

"GET /?code=abc123....123abc&locationid=1&hostname=api.pcloud.com "

Is there a way to save the token so it can be reused?

copy_file doesn't work on large files

I want to copy a file that is ~12M to pCloud.
To do it, I'm using the following code that is using pyfilesystem2

import fs
import urllib
from pcloud import PyCloud
import requests
import logging
import http.client as http_client



http_client.HTTPConnection.debuglevel = 1

# You must initialize logging, otherwise you'll not see debug output.
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True

with fs.open_fs('pcloud://{username}:{password}@/'.format(
        username=urllib.parse.quote_plus('***'),
        password=urllib.parse.quote_plus('***'))) as pcloud_fs:
    with fs.opener.open_fs('/') as linux_fs:
        fs.copy.copy_file(src_fs=linux_fs,
                          src_path='/var/lib/fail2ban/fail2ban.sqlite3',
                          dst_fs=pcloud_fs,
                          dst_path='/fail2ban.sqlite3')
        print('Completed')

This is what I'm getting back

DEBUG:pycloud:Doing request to https://api.pcloud.com/getdigest
DEBUG:pycloud:Params: {}
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.pcloud.com:443
send: b'GET /getdigest HTTP/1.1\r\nHost: api.pcloud.com\r\nUser-Agent: python-requests/2.21.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Server: CloudHTTPd-API v1.1
header: Date: Wed, 27 Mar 2019 20:33:19 GMT
header: Content-Type: application/json; charset=utf-8
header: Content-Length: 138
header: ETag: "***"
header: Cache-Control: private, max-age=0
header: Vary: Accept-Encoding
header: Connection: keep-alive
header: Keep-Alive: timeout=1800
DEBUG:urllib3.connectionpool:https://api.pcloud.com:443 "GET /getdigest HTTP/1.1" 200 138
DEBUG:pycloud:Doing request to https://api.pcloud.com/userinfo
DEBUG:pycloud:Params: {'getauth': 1, 'logout': 1, 'username': '***', 'digest': '***', 'passworddigest': '***'}
send: b'GET /userinfo?getauth=1&logout=1&username=***&digest=***&passworddigest=*** HTTP/1.1\r\nHost: api.pcloud.com\r\nUser-Agent: python-requests/2.21.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Server: CloudHTTPd-API v1.1
header: Date: Wed, 27 Mar 2019 20:33:19 GMT
header: Content-Type: application/json; charset=utf-8
header: Content-Length: 744
header: ETag: "***"
header: Cache-Control: private, max-age=0
header: Vary: Accept-Encoding
header: Connection: keep-alive
header: Keep-Alive: timeout=1800
DEBUG:urllib3.connectionpool:https://api.pcloud.com:443 "GET /userinfo?getauth=1&logout=1&username=***&digest=***&passworddigest=*** HTTP/1.1" 200 744
DEBUG:pycloud:Doing request to https://api.pcloud.com/file_open
DEBUG:pycloud:Params: {'auth': '***', 'path': '/fail2ban.sqlite3', 'flags': 64}
send: b'GET /file_open?auth=***&path=%2Ffail2ban.sqlite3&flags=64 HTTP/1.1\r\nHost: api.pcloud.com\r\nUser-Agent: python-requests/2.21.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Server: CloudHTTPd-API v1.1
header: Date: Wed, 27 Mar 2019 20:33:20 GMT
header: Content-Type: application/json; charset=utf-8
header: Content-Length: 50
header: ETag: "***"
header: Cache-Control: private, max-age=0
header: Vary: Accept-Encoding
header: Connection: keep-alive
header: Keep-Alive: timeout=1800
DEBUG:urllib3.connectionpool:https://api.pcloud.com:443 "GET /file_open?auth=***&path=%2Ffail2ban.sqlite3&flags=64 HTTP/1.1" 200 50
send: b'POST /file_write HTTP/1.1\r\nHost: api.pcloud.com\r\nUser-Agent: python-requests/2.21.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nContent-Length: 2097594\r\nContent-Type: multipart/form-data; boundary=***\r\n\r\n'
send: b'--***\r\nContent-Disposition: form-data; name="fd"\r\n\r\n1\r\n--***\r\nContent-Disposition: form-data; name="data"\r\n\r\nSQLite format 3\x00\x10\x00\x01\x01\x00@  *****'
DEBUG:pycloud:Doing request to https://api.pcloud.com/file_close
DEBUG:pycloud:Params: {'auth': '***', 'fd': 1}
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (2): api.pcloud.com:443
send: b'GET /file_close?auth=***&fd=1 HTTP/1.1\r\nHost: api.pcloud.com\r\nUser-Agent: python-requests/2.21.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Server: CloudHTTPd-API v1.1
header: Date: Wed, 27 Mar 2019 20:33:21 GMT
header: Content-Type: application/json; charset=utf-8
header: Content-Length: 67
header: X-Error: 1007
header: ETag: "***"
header: Cache-Control: private, max-age=0
header: Vary: Accept-Encoding
header: Connection: keep-alive
header: Keep-Alive: timeout=1800
DEBUG:urllib3.connectionpool:https://api.pcloud.com:443 "GET /file_close?auth=***&fd=1 HTTP/1.1" 200 67
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 600, in urlopen
    chunked=chunked)
  File "/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 354, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/usr/local/lib/python3.7/http/client.py", line 1229, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/local/lib/python3.7/http/client.py", line 1275, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/usr/local/lib/python3.7/http/client.py", line 1224, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/local/lib/python3.7/http/client.py", line 1055, in _send_output
    self.send(chunk)
  File "/usr/local/lib/python3.7/http/client.py", line 977, in send
    self.sock.sendall(data)
  File "/usr/local/lib/python3.7/ssl.py", line 1015, in sendall
    v = self.send(byte_view[count:])
  File "/usr/local/lib/python3.7/ssl.py", line 984, in send
    return self._sslobj.write(data)
ConnectionResetError: [Errno 104] Connection reset by peer

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/requests/adapters.py", line 449, in send
    timeout=timeout
  File "/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 638, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "/usr/local/lib/python3.7/site-packages/urllib3/util/retry.py", line 367, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "/usr/local/lib/python3.7/site-packages/urllib3/packages/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 600, in urlopen
    chunked=chunked)
  File "/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 354, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/usr/local/lib/python3.7/http/client.py", line 1229, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/local/lib/python3.7/http/client.py", line 1275, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/usr/local/lib/python3.7/http/client.py", line 1224, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/local/lib/python3.7/http/client.py", line 1055, in _send_output
    self.send(chunk)
  File "/usr/local/lib/python3.7/http/client.py", line 977, in send
    self.sock.sendall(data)
  File "/usr/local/lib/python3.7/ssl.py", line 1015, in sendall
    v = self.send(byte_view[count:])
  File "/usr/local/lib/python3.7/ssl.py", line 984, in send
    return self._sslobj.write(data)
urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test.py", line 76, in <module>
    dst_path='/fail2ban.sqlite3')
  File "/usr/local/lib/python3.7/site-packages/fs/copy.py", line 144, in copy_file
    _dst_fs.upload(dst_path, read_file)
  File "/usr/local/lib/python3.7/site-packages/fs/base.py", line 1313, in upload
    tools.copy_file_data(file, dst_file, chunk_size=chunk_size)
  File "/usr/local/lib/python3.7/site-packages/fs/tools.py", line 57, in copy_file_data
    write(chunk)
  File "/usr/local/lib/python3.7/site-packages/pcloud/pcloudfs.py", line 51, in write
    self.pcloud.file_write(fd=self.fd, data=b)
  File "/usr/local/lib/python3.7/site-packages/pcloud/validate.py", line 20, in wrapper
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/pcloud/api.py", line 221, in file_write
    return self._upload('file_write', files, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/pcloud/api.py", line 112, in _upload
    data=kwargs)
  File "/usr/local/lib/python3.7/site-packages/requests/sessions.py", line 581, in post
    return self.request('POST', url, data=data, json=json, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/requests/sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.7/site-packages/requests/sessions.py", line 646, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/requests/adapters.py", line 498, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))

From what I undestand from the above, what I'm getting back is basically header: X-Error: 1007, which is
1007 Invalid or closed file descriptor.
https://docs.pcloud.com/methods/fileops/file_write.html

The problem I think is that pycloud doesn't wait for the HTTP call to /file_write
https://github.com/tomgross/pycloud/blob/6d7429ff91e021183e2a5131d09ef5735e0f1085/src/pcloud/pcloudfs.py#L51
but instead it tries to close the file descriptor immediately with /file_close

This instead is what I get if I try to upload a text file that contains only "HelloWorld", where I can clearly see the urllib3.connectionpool to /file_write:

DEBUG:pycloud:Doing request to https://api.pcloud.com/getdigest
DEBUG:pycloud:Params: {}
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.pcloud.com:443
send: b'GET /getdigest HTTP/1.1\r\nHost: api.pcloud.com\r\nUser-Agent: python-requests/2.21.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Server: CloudHTTPd-API v1.1
header: Date: Wed, 27 Mar 2019 20:45:17 GMT
header: Content-Type: application/json; charset=utf-8
header: Content-Length: 138
header: ETag: "***"
header: Cache-Control: private, max-age=0
header: Vary: Accept-Encoding
header: Connection: keep-alive
header: Keep-Alive: timeout=1800
DEBUG:urllib3.connectionpool:https://api.pcloud.com:443 "GET /getdigest HTTP/1.1" 200 138
DEBUG:pycloud:Doing request to https://api.pcloud.com/userinfo
DEBUG:pycloud:Params: {'getauth': 1, 'logout': 1, 'username': '***', 'digest': '***', 'passworddigest': '***'}
send: b'GET /userinfo?getauth=1&logout=1&username=***&digest=***&passworddigest=*** HTTP/1.1\r\nHost: api.pcloud.com\r\nUser-Agent: python-requests/2.21.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Server: CloudHTTPd-API v1.1
header: Date: Wed, 27 Mar 2019 20:45:17 GMT
header: Content-Type: application/json; charset=utf-8
header: Content-Length: 744
header: ETag: "***"
header: Cache-Control: private, max-age=0
header: Vary: Accept-Encoding
header: Connection: keep-alive
header: Keep-Alive: timeout=1800
DEBUG:urllib3.connectionpool:https://api.pcloud.com:443 "GET /userinfo?getauth=1&logout=1&username=***&digest=***&passworddigest=*** HTTP/1.1" 200 744
DEBUG:pycloud:Doing request to https://api.pcloud.com/file_open
DEBUG:pycloud:Params: {'auth': '***', 'path': '/fail2ban.sqlite3', 'flags': 64}
send: b'GET /file_open?auth=***&path=%2Ffail2ban.sqlite3&flags=64 HTTP/1.1\r\nHost: api.pcloud.com\r\nUser-Agent: python-requests/2.21.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Server: CloudHTTPd-API v1.1
header: Date: Wed, 27 Mar 2019 20:45:17 GMT
header: Content-Type: application/json; charset=utf-8
header: Content-Length: 50
header: ETag: "***"
header: Cache-Control: private, max-age=0
header: Vary: Accept-Encoding
header: Connection: keep-alive
header: Keep-Alive: timeout=1800
DEBUG:urllib3.connectionpool:https://api.pcloud.com:443 "GET /file_open?auth=***&path=%2Ffail2ban.sqlite3&flags=64 HTTP/1.1" 200 50
send: b'POST /file_write HTTP/1.1\r\nHost: api.pcloud.com\r\nUser-Agent: python-requests/2.21.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nContent-Length: 464\r\nContent-Type: multipart/form-data; boundary=***\r\n\r\n'
send: b'--***\r\nContent-Disposition: form-data; name="fd"\r\n\r\n1\r\n--***\r\nContent-Disposition: form-data; name="data"\r\n\r\nHelloWorld\n\r\n--***\r\nContent-Disposition: form-data; name="auth"\r\n\r\n***\r\n--***\r\nContent-Disposition: form-data; name="filename"; filename="filename"\r\n\r\nHelloWorld\n\r\n--***--\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Server: CloudHTTPd-API v1.1
header: Date: Wed, 27 Mar 2019 20:45:17 GMT
header: Content-Type: application/json; charset=utf-8
header: Content-Length: 30
header: ETag: "***"
header: Cache-Control: private, max-age=0
header: Vary: Accept-Encoding
header: Connection: keep-alive
header: Keep-Alive: timeout=1800
DEBUG:urllib3.connectionpool:https://api.pcloud.com:443 "POST /file_write HTTP/1.1" 200 30
DEBUG:pycloud:Doing request to https://api.pcloud.com/file_close
DEBUG:pycloud:Params: {'auth': '***', 'fd': 1}
send: b'GET /file_close?auth=***&fd=1 HTTP/1.1\r\nHost: api.pcloud.com\r\nUser-Agent: python-requests/2.21.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Server: CloudHTTPd-API v1.1
header: Date: Wed, 27 Mar 2019 20:45:17 GMT
header: Content-Type: application/json; charset=utf-8
header: Content-Length: 16
header: ETag: "***"
header: Cache-Control: private, max-age=0
header: Vary: Accept-Encoding
header: Connection: keep-alive
header: Keep-Alive: timeout=1800
DEBUG:urllib3.connectionpool:https://api.pcloud.com:443 "GET /file_close?auth=***&fd=1 HTTP/1.1" 200 16
Completed

and as you can see the file is uploaded successfully.
Have I understood correctly the problem?
If so, would you be able to give me any hint on how I can make file_close to wait on the file_write?

System info:
python:3.7 Docker container with Python 3.7.2
appdirs==1.4.3
certifi==2019.3.9
chardet==3.0.4
fs==2.4.4
idna==2.8
pcloud==1.0a6
pytz==2018.9
PyYAML==5.1
requests==2.21.0
six==1.12.0
urllib3==1.24.1

Thanks

Massimo

Release on pypi

Great job!

But have you deleted this from pip distribution? Or maybe some other reason?

Cheer up!

Thanks!

Status

Hi @tomgross,
I came across this repository, and was wondering what your plans are with it.
Are you continuing on with it or would you be interested in pull request.
Regards
Shawn

builtins.TypeError: _upload() got multiple values for argument 'files'

Hi.
When using PyCloud.uploadfile method with files argument I am getting exception
builtins.TypeError: _upload() got multiple values for argument 'files'
Sample dataset which is raising exception:
folderid = 1143455235, files = <list 0x7fdfbd05dd48; len=1>, progresshash = "7KzBBeJcNbV8NhbRi2kM6UUvobJ85nzD", nopartial = 1, filename = "test"
files list content: 0 = "priv/testSource/test"
I guess that there may be problem with name of argument in _upload method. There is files argument but also in **kwargs You are passing 'files' argument. When I changed in api.py name of one of these arguments exeption is not raised.

Endpoint with opener?

I wonder if I can set the endpoint somehow when uing the opener?
with opener.open_fs(f"pcloud://{user}:{pw}@/") as pcloud_fs:
Thanks

Downloading a file.

Since full docs is missing, can I ask you to please update the README file to include a snippet of how to download a file? There is already 2 lines showing the upload, adding the download will make it complete.

cannot use folderid with uploadfile method

In my script that uses pycloud I cannot use folderid=folderid, where folderid is an integer, with the uploadfile method. It causes some exceptions and doesn't upload the file.

My script has fileinfo = pc.uploadfile(files=[upload_file], folderid=folderid) and is causes exceptions (see below). I have to change the folderid=folderid to path='/' like below:

fileinfo = pc.uploadfile(files=[upload_file], path='/')

The pcloud api says that path is discouraged but still accepted. In lieu of path it provides a folderid parameter: https://docs.pcloud.com/methods/file/uploadfile.html

Exceptions when folderid is used with pycloud.uploadfile:

  File "/pcloud-upload/./pcloud-upload.py", line 215, in <module>
    fileinfo = pc.uploadfile(files=[upload_file], folderid=folderid)
  File "/home/alarm/.local/lib/python3.10/site-packages/pcloud/validate.py", line 19, in wrapper
    return func(*args, **kwargs)
  File "/home/alarm/.local/lib/python3.10/site-packages/pcloud/api.py", line 274, in uploadfile
    return self._upload("uploadfile", files, **kwargs)
  File "/home/alarm/.local/lib/python3.10/site-packages/pcloud/api.py", line 242, in _upload
    m = MultipartEncoder(fields=fields)
  File "/usr/lib/python3.10/site-packages/requests_toolbelt/multipart/encoder.py", line 125, in __init__
    self._prepare_parts()
  File "/usr/lib/python3.10/site-packages/requests_toolbelt/multipart/encoder.py", line 246, in _prepare_parts
    self.parts = [Part.from_field(f, enc) for f in self._iter_fields()]
  File "/usr/lib/python3.10/site-packages/requests_toolbelt/multipart/encoder.py", line 246, in <listcomp>
    self.parts = [Part.from_field(f, enc) for f in self._iter_fields()]
  File "/usr/lib/python3.10/site-packages/requests_toolbelt/multipart/encoder.py", line 494, in from_field
    body = coerce_data(field.data, encoding)
  File "/usr/lib/python3.10/site-packages/requests_toolbelt/multipart/encoder.py", line 472, in coerce_data
    return CustomBytesIO(data, encoding)
  File "/usr/lib/python3.10/site-packages/requests_toolbelt/multipart/encoder.py", line 535, in __init__
    buffer = encode_with(buffer, encoding)
  File "/usr/lib/python3.10/site-packages/requests_toolbelt/multipart/encoder.py", line 416, in encode_with
    return string.encode(encoding)
AttributeError: 'int' object has no attribute 'encode'

When I change folderid to using path then I get expected result, the file is uploaded.

raceback (most recent call last): File "main.py", line 31, in check_update pc.file_open(path='/SITI_BuildFirst.zip', flags=api.O_CREAT) NameError: name 'api' is not defined

I want to make a system for updating the game, but when the update starts, it gives such an error, what should I do?)

My update code:

from pcloud import PyCloud

pc = PyCloud('[email protected]', 'myPassword')

def check_update():
print("Updating...")
ui.StatusText.setText("Downloading...")
pc.file_open(path='/SITI_BuildFirst.zip', flags=api.O_CREAT)

Protocol: Binary vs HTTP/JSON

Hi,

Thanks for this small and handy library.

This is not really an issue at all, but rather a question to the developers who actually went through the process of implementing the API: So, I was long wondering what the difference between the "binary" [1] and the "HTTP/JSON" [2] protocol is? The description on https://docs.pcloud.com/ doesn't really make that clear (at least to me).

Does pycloud implement both? And do you have any experience in which one would be fast/better?

Thanks,
Armin

[1] https://docs.pcloud.com/protocols/binary_protocol/
[2] https://docs.pcloud.com/protocols/http_json_protocol/

Download file from public link

Is there a way to download the content of a file via its public link? I want to access the file without having to log into my account.

Thanks!

async file upload

Hi. I am trying to use the module asyncio to asynchronously upload files to my pcloud folder but it always blocks waits for the upload to be terminate before doing the next line

Do you have any idea of what I'm doing wrong ?

from dotenv import load_dotenv
import os
import asyncio


async def call_this(connection,file):
    await uploadfile(connection,file)

async def uploadfile(connection,file):
    await connection.uploadfile(files = file)
    print("done")

load_dotenv()

pcloud_user = os.environ.get("PCLOUD_USER")
pcloud_password = os.environ.get("PCLOUD_PASSWORD")

connection = PyCloud(pcloud_user, pcloud_password)



asyncio.run(call_this(connection,["test.png","test2.png"]))

Can't upload file with OAuth authentication

Hi,

I can use OAuth authentication with pc = PyCloud("", "LecVZx4nurbtMY1BZUkjfi7ZTyW7azxsy6SyO0j3pJXGRjIMPOdy", endpoint="eapi", oauth2=True). This works on some methods, such as userinfo() and listfolder(folderid=0). However it doesn't with uploadfile(), I get the error {'result': 2000, 'error': 'Log in failed.'}. Inspecting the code it seems that the method uploadfile() is using auth_code, which is initialized empty when using OAuth authentication. Is it possible to use uploadfile() with OAuth authentication?

Thanks!

Hash

Do you know how they calculate hash (hash: 5380817599554757000)? I did not find anything in the documentation.

{
    result: 0,
    metadata: {
        icon: "folder",
        id: "d0",
        modified: "Thu, 19 Sep 2013 07:31:46 +0000",
        path: "/",
        thumb: false,
        created: "Thu, 19 Sep 2013 07:31:46 +0000",
        folderid: 0,
        isshared: false,
        isfolder: true,
        ismine: true,
        name: "/",
        contents: [
            {
                icon: "audio",
                contenttype: "audio/mpeg",
                parentfolderid: 0,
                modified: "Wed, 02 Oct 2013 13:23:19 +0000",
                path: "/Simple Audio.mp3",
                hash: 5380817599554757000,
                thumb: false,
                created: "Wed, 02 Oct 2013 13:23:19 +0000",
                id: "f1723778",
                ismine: true,
                category: 3,
                fileid: 1723778,
                isshared: false,
                isfolder: false,
                name: "Simple Audio.mp3",
                size: 11252576
            }]
    }
}

PyPi lists LICENSE as MIT

When checking the LICENSE from command line or via PyPi site, this library shows up as MIT but README shows it is GPLv2 License which is quite different.

image

Thanks.

How to use the downloadfile method?

Im able to upload files but i struggle to understand the downloadfile method.
Does anyone have a simple code example for downloading a file?

Problem on open

from fs import opener
link = 'pcloud://' + uname + ':' + password + '@/'
        with opener.open_fs(link) as openfs:
            file = openfs.open('/1.json')
            print(file.read())

==================================================
{
"result": 1011,
"error": "Please provide 'count'."
}

Passing list to pc.uploadfile gives exception

In my script I use argparse to accept a '--file' parameter where I can specify a single or multiple files to upload to pcloud:

clp.add_argument('-f', '--file', type=argparse.FileType('r'), nargs='+',
                  help='List of local FILEs to upload')
clargs = clp.parse_args()

by running it like so:

./pcloud-upload.py -f ./README.md ./LICENSE

and when this happens, my script passes clargs.file (a python list) to uploadfile in pycloud but throws following exception(s):

Traceback (most recent call last):
  File "/home/alarm/dev/pcloud-upload/./pcloud-upload.py", line 227, in <module>
    fileinfo = pc.uploadfile(files=[pc_uploadlist], path='/') # folderid=folderid) # path=upload_dir)
  File "/home/alarm/.local/lib/python3.10/site-packages/pcloud/validate.py", line 19, in wrapper
    return func(*args, **kwargs)
  File "/home/alarm/.local/lib/python3.10/site-packages/pcloud/api.py", line 265, in uploadfile
    files = [
  File "/home/alarm/.local/lib/python3.10/site-packages/pcloud/api.py", line 266, in <listcomp>
    ("file", (os.path.split(f)[1], open(f, "rb"))) for f in upload_files
  File "/usr/lib/python3.10/posixpath.py", line 103, in split
    p = os.fspath(p)
TypeError: expected str, bytes or os.PathLike object, not list

I thought it might have been the argparse.FileType('r') was the problem with an improper cast to a list, which is what I believe pycloud will accept for more than one file. But when I removed argparse.FileType('r') from the argparse part of the script, I got the same exception(s). To remove the issue with perhaps argparse being the problem, I hardcoded a list to be sent to pc.uploadfile like so:

upload_files = ['./README.md', './LICENSE']
pc_uploadlist = upload_files
fileinfo = pc.uploadfile(files=[pc_uploadlist], path='/')

and I get the exact same set of exceptions as above.

In your uploadfile function https://github.com/tomgross/pycloud/blob/master/src/pcloud/api.py#L251 you go through your kwargs files and pop off each item in the list but I'm not sure if this is working properly for accepting a list for uploadfile.

In my script, before I used argparse, I was just passing my --file command line option using a variable and pcloud would upload it properly. So I feel that the api's uploadfile function is not accepting a list and processing that list properly.

Testing some more - I only pass a single file to argparse like so ./pcloud-upload.py -f ./README.md and changing my script line above from:

fileinfo = pc.uploadfile(files=[pc_uploadlist], path='/')

to

fileinfo = pc.uploadfile(files=clargs.file, path='/') 

works properly and uploaded the single file. But I cannot pass two files to my script.

Some example how to download files

I have an url like this:
https://e.pcloud.link/publink/show?code=XZJl5XZsC9sU0xDCFu4OzaHrVuNypt2YvUi

`
import requests
import json

uurl='https://eapi.pcloud.com/'

url='https://e.pcloud.link/publink/show?code=XZJl5XZsC9sU0xDCFu4OzaHrVuNypt2YvUi'

f=[]
resp= requests.post(uurl+'downloadfile',
data={
'url':url,
'username':'[email protected]',
'password':'somepassword',
}
)
if json:
resp = resp.json()
else:
resp = resp.content
print(resp)
`
But it gives me only dictionary.
How can i download file to my local directory?

Data samples

Hi!
I'm trying to implement the binary protocol in a different language but I end up with some weird results...
Would it be possible to have some byte representation of a command and the result? Like what would be a listfolder with a random auth key? And its result?

OAuth 2.0 authentication

When using OAuth 2.0 authentication, as follow:

from pcloud import PyCloud
pc = api.PyCloud.oauth2_authorize(client_id="stg", client_secret="stg123")
pc.listfolder(folderid=0)

The output is:
Traceback (most recent call last):
File "", line 1, in
NameError: name 'api' is not defined

by doing "from pcloud import api"
The output is:
AttributeError: type object 'PyCloud' has no attribute 'oauth2_authorize'

Any help would be appreciated.

Uploading Images

I'm trying to upload an image to a given pCloud path

>>> from pcloud import PyCloud
>>> pc = PyCloud('MyID','MyPSW')
>>> pc.uploadfile(filename='image.jpg', data='What goes here?', path='/path-to-pcloud-dir')
That creates a file in a pcloud given path with the text 'What goes here?'

As data I tried  Image.open, Image.fromarray, io.BytesIO, image.to bytes but always 
I get "AttributeError: 'JpegImageFile' object has no attribute 'read'"

For example:
>>>from PIL import Image
>>>i=Image.open('image.jpg','r')
>>> pc.uploadfile(filename='image.jpg', data=i, path='/path-to-pcloud-dir')

Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python3.7/dist-packages/pcloud/validate.py", line 20, in wrapper
return func(*args, **kwargs)
File "/usr/local/lib/python3.7/dist-packages/pcloud/api.py", line 135, in uploadfile
return self._upload('uploadfile', files, **kwargs)
File "/usr/local/lib/python3.7/dist-packages/pcloud/api.py", line 112, in _upload
data=kwargs)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 581, in post
return self.request('POST', url, data=data, json=json, **kwargs)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 519, in request
prep = self.prepare_request(req)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 462, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "/usr/lib/python3/dist-packages/requests/models.py", line 316, in prepare
self.prepare_body(data, files, json)
File "/usr/lib/python3/dist-packages/requests/models.py", line 504, in prepare_body
(body, content_type) = self._encode_files(files, data)
File "/usr/lib/python3/dist-packages/requests/models.py", line 169, in _encode_files
body, content_type = encode_multipart_formdata(new_fields)
File "/usr/lib/python3/dist-packages/urllib3/filepost.py", line 90, in encode_multipart_formdata
body.write(data)
TypeError: a bytes-like object is required, not 'JpegImageFile'

Can't use OAuth 2.0 authentication

Hi,

I'm trying to use OAuth 2.0 authentication, but when I do the program gets stuck (it does not finish after 10 minutes). When I interrupt, I get this message:

pc = PyCloud.oauth2_authorize(client_id=client_id, client_secret=client_secret)
^CTraceback (most recent call last):
File "", line 1, in
File "/home/ec2-user/.local/lib/python3.7/site-packages/pcloud/api.py", line 109, in oauth2_authorize
code, hostname = TokenHandler(client_id).get_access_token()
File "/home/ec2-user/.local/lib/python3.7/site-packages/pcloud/oauth2.py", line 44, in get_access_token
httpServer.handle_request()
File "/usr/lib64/python3.7/socketserver.py", line 294, in handle_request
ready = selector.select(timeout)
File "/usr/lib64/python3.7/selectors.py", line 415, in select
fd_event_list = self._selector.poll(timeout)
KeyboardInterrupt

I have set the redirect URI to http://localhost:65432/, and the port is available on my machine.

I have also tried to log in using email + password, and everything seems to work fine (using eapi endpoint).

Any idea what's going on with the OAuth 2.0 authentication?

I'm using the version 1.0b1.

Many thanks.

Can't authenticate with 2-factor authentication enabled

I'm not sure if 2-factor authentication is supported in the library but I can't seem to find a way to do that.
Apparently the pCloud APIs do not support 2-factor authentication yet so this may need to wait for the implementation on their side.

How to copy/upload file using fs

I'm trying to understand how to copy/upload a file using pyfilesystem2.
I have tried with the following:

import fs
from pcloud import PyCloud
import urllib.parse

username = urllib.parse.quote_plus('my_username')
password = urllib.parse.quote_plus('my_password')

with fs.opener.open_fs('pcloud://{0}:{1}@/'.format(username, password)) as pcloud_fs:
    pcloud_fs.copy('/opt/software/db.sqlite3', '/backup/software/', True)

but I'm always getting

OSError: pCloud error occured (2002) - A component of parent directory does not exist.

even if /backup/software/ already exists on pCloud.
I have changed the log.debug to a print here and added a print for resp.json()
https://github.com/tomgross/pycloud/blob/31d9676446de3e417396e296dd4a95441983173e/src/pcloud/api.py#L55-L59
and this is what I'm getting back

Doing request to %s%s https://api.pcloud.com/ file_open
Params: %s {'auth': '***, 'path': '/opt/software/db.sqlite3', 'flags': 64}
{'result': 2002, 'error': 'A component of parent directory does not exist.'}

so it looks like it is inverting src_path with dst_path.

I'm using fs==2.4.11 and the copy function as from what I understand is copying files from one filesystem to another:
https://github.com/PyFilesystem/pyfilesystem2/blob/v2.4.11/fs/base.py#L401-L402

I'm trying to debug the issue but any help is appreciated.

share file

How can i get shareable link of a file

Error while using makedirs from PyFilesystem

Hi,
I'm getting an error while trying to use makedirs from PyFilesystem with pycloud.
As per documentation from PyFilesystem
https://docs.pyfilesystem.org/en/latest/reference/base.html#fs.base.FS.makedirs

Make a directory, and any missing intermediate directories.

Using this code

import fs
from pcloud import PyCloud
import urllib.parse

username = urllib.parse.quote_plus('my_username')
password = urllib.parse.quote_plus('my_password')

with fs.opener.open_fs('pcloud://{0}:{1}@/'.format(username, password)) as pcloud_fs:
    pcloud_fs.makedirs(path='/backup/second_level/third_level', recreate=True)

I'm getting the following error

Traceback (most recent call last):
  File "fs_makedirs.py", line 10, in <module>
    pcloud_fs.makedirs(path='/backup/second_level/third_level', recreate=True)
  File "/usr/local/lib/python3.6/site-packages/fs/base.py", line 1035, in makedirs
    dir_paths = tools.get_intermediate_dirs(self, path)
  File "/usr/local/lib/python3.6/site-packages/fs/tools.py", line 82, in get_intermediate_dirs
    resource = fs.getinfo(path)
  File "/usr/local/lib/python3.6/site-packages/pcloud/pcloudfs.py", line 118, in getinfo
    for item in folder_list['metadata']['contents']:
KeyError: 'metadata'

where:
/backup: it exists
/backup/second_level: it doesn't exist
/backup/third_level: it doesn't exist

and getinfo tries to fetch metadata of a directory that doesn't exist (parent_path = /backup/second_level).

Versions used in this test:
macOS 10.11.6
Python 3.6.5
fs==2.0.27
pcloud==1.0a4

Regards

Massimo

Error with python 2.7

TypeError: str() takes at most 1 argument (2 given)

Traceback (most recent call last):
(...)
File "C:\Python27\lib\site-packages\pcloud\api.py", line 48, in init
self.auth_token = self.get_auth_token()
File "C:\Python27\lib\site-packages\pcloud\api.py", line 73, in get_auth_token
bytes(sha1(self.username).hexdigest(), 'utf-8') +
TypeError: str() takes at most 1 argument (2 given)

When trying to use 'listtokens' I get error 1000 'Login is required'

I've successfully used the api for my script but when trying to determine and use the call listtokens to see if my tokens have expired or when they will expire, the api returns the following error:

{'result': 1000, 'error': 'Log in required.'}

I'm using oauth2 as my authenication. The listtokens command doesn't take any input: https://docs.pcloud.com/methods/auth/listtokens.html
To start my script off (as it's in it's beginning stage) I've written a 'list folders' function and that works fine. So it's not that I'm not logged in, it must be something else.

Any ideas?

(Feature Request) Create folders that do not exist

Example of current behavior:
When uploading you specify path=/dir1/dir2/dir3/file.txt
But in your pcloud you only have /dir1/dir2
Instead of creating dir3, currently pcloud just silently doesn't do the upload.

It would be nice if pycloud could create the missing directories when uploading a file. A different feature that could be easier to implement but still super useful is adding a method to create folders, so from the example I could create dir3 then upload the file.

My use case is I want to upload files from different days and organize them like /year/month/day

New pCloud API Server

I use correct email and password but authentication fails. I tried 2 different pcloud accounts, all of them work in browser but do not work through PyCloud.

from pcloud import PyCloud
pc = PyCloud(myemail, mypassword)

  File "C:\Users\Asm\miniconda3\lib\site-packages\pcloud\api.py", line 47, in __init__
    self.auth_token = self.get_auth_token()
  File "C:\Users\Asm\miniconda3\lib\site-packages\pcloud\api.py", line 82, in get_auth_token
    raise (AuthenticationError)
pcloud.api.AuthenticationError

Windows 10 64, Python 3.7.7, pcloud 1.0a8 (pip install -U pcloud).
Debug log:

2020-07-04 15:42:54,431 pycloud  Doing request to https://api.pcloud.com/getdigest
2020-07-04 15:42:54,431 pycloud  Params: {}
2020-07-04 15:42:55,228 pycloud  Doing request to https://api.pcloud.com/userinfo
2020-07-04 15:42:55,228 pycloud  Params: {'getauth': 1, 'logout': 1, 'username': '[email protected]', 'digest': 'pCloudpCloudpCloudZCyCuOpv68cIlKo537ZCa6vKmxV2NLyoyGO8UlreN', 'passworddigest': '08e08d87d32bea4ei05e33e789e3377b92a6udd1'}

getdigest response:

{'result': 0, 'expires': 'Sat, 04 Jul 2020 11:01:43 +0000', 'digest': 'pCloudpCloudpCloudZt789Bu6AADVZdco642ZYI7LYgRc8kFxf1HVHjTHTh'}

get_auth_token response:

{'result': 2000, 'error': 'Log in failed.'}

I can't upload files

I can't upload files

files = ['out.csv', 'vix.csv']
pc.uploadfile(files)

this is the message it gives me

ValueError: Required parameter ``data, files`` is missing.

what does this refer to? Until yesterday I could upload files without problem

SSL related connection errors when uploading files

Hello Tom
First of all, thanks for your great work creating this python library. It will hopefully save me a lot of hassle in the future with uploading my backups to pcloud. I'm trying to upload a bunch of files to pcloud (a few hundred). For this, I'm generating a list of file names and upload these as soon as I have 11 files in the list. I'm using, a line like this to upload my files:
cloudrive.uploadfile(folderid=bBSID, files=uploadBuffer)
uploadBuffer is a list of file paths. This works fine for a while, but sooner or later I'm getting the follwoing error and the script stops:
`Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/urllib3/contrib/pyopenssl.py", line 317, in _send_until_done
return self.connection.send(data)
File "/usr/lib/python3/dist-packages/OpenSSL/SSL.py", line 1737, in send
self._raise_ssl_error(self._ssl, result)
File "/usr/lib/python3/dist-packages/OpenSSL/SSL.py", line 1639, in _raise_ssl_error
raise SysCallError(errno, errorcode.get(errno))
OpenSSL.SSL.SysCallError: (104, 'ECONNRESET')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 600, in urlopen
chunked=chunked)
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 354, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/usr/lib/python3.7/http/client.py", line 1260, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/lib/python3.7/http/client.py", line 1306, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "/usr/lib/python3.7/http/client.py", line 1255, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/lib/python3.7/http/client.py", line 1069, in _send_output
self.send(chunk)
File "/usr/lib/python3.7/http/client.py", line 991, in send
self.sock.sendall(data)
File "/usr/lib/python3/dist-packages/urllib3/contrib/pyopenssl.py", line 328, in sendall
sent = self._send_until_done(data[total_sent:total_sent + SSL_WRITE_BLOCKSIZE])
File "/usr/lib/python3/dist-packages/urllib3/contrib/pyopenssl.py", line 323, in _send_until_done
raise SocketError(str(e))
OSError: (104, 'ECONNRESET')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/requests/adapters.py", line 449, in send
timeout=timeout
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 638, in urlopen
_stacktrace=sys.exc_info()[2])
File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 367, in increment
raise six.reraise(type(error), error, _stacktrace)
File "/usr/lib/python3/dist-packages/six.py", line 692, in reraise
raise value.with_traceback(tb)
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 600, in urlopen
chunked=chunked)
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 354, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/usr/lib/python3.7/http/client.py", line 1260, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/lib/python3.7/http/client.py", line 1306, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "/usr/lib/python3.7/http/client.py", line 1255, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/lib/python3.7/http/client.py", line 1069, in _send_output
self.send(chunk)
File "/usr/lib/python3.7/http/client.py", line 991, in send
self.sock.sendall(data)
File "/usr/lib/python3/dist-packages/urllib3/contrib/pyopenssl.py", line 328, in sendall
sent = self._send_until_done(data[total_sent:total_sent + SSL_WRITE_BLOCKSIZE])
File "/usr/lib/python3/dist-packages/urllib3/contrib/pyopenssl.py", line 323, in _send_until_done
raise SocketError(str(e))
urllib3.exceptions.ProtocolError: ('Connection aborted.', OSError("(104, 'ECONNRESET')"))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
self.run()
File "/usr/lib/python3.7/multiprocessing/process.py", line 99, in run
self._target(*self._args, **self._kwargs)
File "./pCloudBackup.py", line 112, in uploadFiles
cloudrive.uploadfile(folderid=bBSID, files=uploadBuffer)
File "/usr/local/lib/python3.7/dist-packages/pcloud/validate.py", line 19, in wrapper
return func(*args, **kwargs)
File "/usr/local/lib/python3.7/dist-packages/pcloud/api.py", line 156, in uploadfile
return self._upload("uploadfile", files, **kwargs)
File "/usr/local/lib/python3.7/dist-packages/pcloud/api.py", line 135, in _upload
resp = self.session.post(self.endpoint + method, files=files, data=kwargs)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 581, in post
return self.request('POST', url, data=data, json=json, **kwargs)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 533, in request
resp = self.send(prep, **send_kwargs)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 646, in send
r = adapter.send(request, **kwargs)
File "/usr/lib/python3/dist-packages/requests/adapters.py", line 498, in send
raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', OSError("(104, 'ECONNRESET')"))
`

The script is running on a debian server with python 3.7.3
I can also send you the full code of my script, if this would help you.

Sync folders between pcloud and local drive

Hi Tom
Great job, i loved your pCloud API

I was wondering if it's possible to add a new feature, adding a sync method !

Well, i tried to use yours to sync two folders as i work on multiple machines and need to stay sync without using a USB drive. Each time, i have to write long script to do that copying and downloading multiple files and recreating folders...

Thanks a lot and goodluck

Running out of memory when uploading large files

Hello,
When my server tries to upload large files, it runs out of memory. Problem seems to be the read() and write() commands that generate the post string. Would it be possible to send large files in chunks somehow?
Here's the error message (the read error is repeated several times in the logs):

Traceback (most recent call last):
  File "/home/USER/customscripts/backup_pcloud/pCloudBackup.py", line 146, in pCloudUpload
    pDrive.uploadfile(folderid=bBSID, files=fileBuf)
  File "/usr/local/lib/python3.7/dist-packages/pcloud/validate.py", line 19, in wrapper
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/pcloud/api.py", line 156, in uploadfile
    return self._upload("uploadfile", files, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/pcloud/api.py", line 135, in _upload
    resp = self.session.post(self.endpoint + method, files=files, data=kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 581, in post
    return self.request('POST', url, data=data, json=json, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 519, in request
    prep = self.prepare_request(req)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 462, in prepare_request
    hooks=merge_hooks(request.hooks, self.hooks),
  File "/usr/lib/python3/dist-packages/requests/models.py", line 316, in prepare
    self.prepare_body(data, files, json)
  File "/usr/lib/python3/dist-packages/requests/models.py", line 504, in prepare_body
    (body, content_type) = self._encode_files(files, data)
  File "/usr/lib/python3/dist-packages/requests/models.py", line 169, in _encode_files
    body, content_type = encode_multipart_formdata(new_fields)
  File "/usr/lib/python3/dist-packages/urllib3/filepost.py", line 90, in encode_multipart_formdata
    body.write(data)
MemoryError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/USER/customscripts/backup_pcloud/pCloudBackup.py", line 134, in pCloudUploadSingle
    pDrive.uploadfile(folderid=uploadFolder, files=[uploadFile])
  File "/usr/local/lib/python3.7/dist-packages/pcloud/validate.py", line 19, in wrapper
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/pcloud/api.py", line 156, in uploadfile
    return self._upload("uploadfile", files, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/pcloud/api.py", line 135, in _upload
    resp = self.session.post(self.endpoint + method, files=files, data=kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 581, in post
    return self.request('POST', url, data=data, json=json, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 519, in request
    prep = self.prepare_request(req)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 462, in prepare_request
    hooks=merge_hooks(request.hooks, self.hooks),
  File "/usr/lib/python3/dist-packages/requests/models.py", line 316, in prepare
    self.prepare_body(data, files, json)
  File "/usr/lib/python3/dist-packages/requests/models.py", line 504, in prepare_body
    (body, content_type) = self._encode_files(files, data)
  File "/usr/lib/python3/dist-packages/requests/models.py", line 159, in _encode_files
    fdata = fp.read()

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.