Giter Club home page Giter Club logo

webdav-client-python's Introduction

webdavclient

PyPI version Requirements Status PullReview stats

Package webdavclient provides easy and convenient work with WebDAV-servers (Yandex.Drive, Dropbox, Google Drive, Box, 4shared, etc.). The package includes the following components: webdav API, resource API and wdc.

The source code of the project can be found here Github

Installation and upgrade

Installation

Linux

$ sudo apt-get install libxml2-dev libxslt-dev python-dev
$ sudo apt-get install libcurl4-openssl-dev python-pycurl 
$ sudo easy_install webdavclient

macOS

$ curl https://bootstrap.pypa.io/ez_setup.py -o - | python
$ python setup.py install --prefix=/opt/setuptools
$ sudo easy_install webdavclient

Update

$ sudo pip install -U webdavclient

Webdav API

Webdav API is a set of webdav methods of work with cloud storage. This set includes the following methods: check, free, info, list, mkdir, clean, copy, move, download, upload, publish and unpublish.

Configuring the client

Required keys for configuring client connection with WevDAV-server are webdav_hostname and webdav_login, webdav,_password.

import webdav.client as wc
options = {
 'webdav_hostname': "https://webdav.server.ru",
 'webdav_login':    "login",
 'webdav_password': "password"
}
client = wc.Client(options)

When a proxy server you need to specify settings to connect through it.

import webdav.client as wc
options = {
 'webdav_hostname': "https://webdav.server.ru",
 'webdav_login':    "w_login",
 'webdav_password': "w_password", 
 'proxy_hostname':  "http://127.0.0.1:8080",
 'proxy_login':     "p_login",
 'proxy_password':  "p_password"
}
client = wc.Client(options)

If you want to use the certificate path to certificate and private key is defined as follows:

import webdav.client as wc
options = {
 'webdav_hostname': "https://webdav.server.ru",
 'webdav_login':    "w_login",
 'webdav_password': "w_password",
 'cert_path':       "/etc/ssl/certs/certificate.crt",
 'key_path':        "/etc/ssl/private/certificate.key"
}
client = wc.Client(options)

Or you want to limit the speed or turn on verbose mode:

options = {
 ...
 'recv_speed' : 3000000,
 'send_speed' : 3000000,
 'verbose'    : True
}
client = wc.Client(options)

recv_speed: rate limit data download speed in Bytes per second. Defaults to unlimited speed.
send_speed: rate limit data upload speed in Bytes per second. Defaults to unlimited speed.
verbose: set verbose mode on/off. By default verbose mode is off.

Synchronous methods

# Checking existence of the resource

client.check("dir1/file1")
client.check("dir1")
# Get information about the resource

client.info("dir1/file1")
client.info("dir1/")
# Check free space

free_size = client.free()
# Get a list of resources

files1 = client.list()
files2 = client.list("dir1")
# Create directory

client.mkdir("dir1/dir2")
# Delete resource

client.clean("dir1/dir2")
# Copy resource

client.copy(remote_path_from="dir1/file1", remote_path_to="dir2/file1")
client.copy(remote_path_from="dir2", remote_path_to="dir3")
# Move resource

client.move(remote_path_from="dir1/file1", remote_path_to="dir2/file1")
client.move(remote_path_from="dir2", remote_path_to="dir3")
# Move resource

client.download_sync(remote_path="dir1/file1", local_path="~/Downloads/file1")
client.download_sync(remote_path="dir1/dir2/", local_path="~/Downloads/dir2/")
# Unload resource

client.upload_sync(remote_path="dir1/file1", local_path="~/Documents/file1")
client.upload_sync(remote_path="dir1/dir2/", local_path="~/Documents/dir2/")
# Publish the resource

link = client.publish("dir1/file1")
link = client.publish("dir2")
# Unpublish resource

client.unpublish("dir1/file1")
client.unpublish("dir2")
# Exception handling

from webdav.client import WebDavException
try:
...
except WebDavException as exception:
...
# Get the missing files

client.pull(remote_directory='dir1', local_directory='~/Documents/dir1')
# Send missing files

client.push(remote_directory='dir1', local_directory='~/Documents/dir1')

Asynchronous methods

# Load resource

kwargs = {
 'remote_path': "dir1/file1",
 'local_path':  "~/Downloads/file1",
 'callback':    callback
}
client.download_async(**kwargs)

kwargs = {
 'remote_path': "dir1/dir2/",
 'local_path':  "~/Downloads/dir2/",
 'callback':    callback
}
client.download_async(**kwargs)
# Unload resource

kwargs = {
 'remote_path': "dir1/file1",
 'local_path':  "~/Downloads/file1",
 'callback':    callback
}
client.upload_async(**kwargs)

kwargs = {
 'remote_path': "dir1/dir2/",
 'local_path':  "~/Downloads/dir2/",
 'callback':    callback
}
client.upload_async(**kwargs)

Resource API

Resource API using the concept of OOP that enables cloud-level resources.

# Get a resource

res1 = client.resource("dir1/file1")
# Work with the resource

res1.rename("file2")
res1.move("dir1/file2")
res1.copy("dir2/file1")
info = res1.info()
res1.read_from(buffer)
res1.read(local_path="~/Documents/file1")
res1.read_async(local_path="~/Documents/file1", callback)
res1.write_to(buffer)
res1.write(local_path="~/Downloads/file1")
res1.write_async(local_path="~/Downloads/file1", callback)

wdc

wdc - a cross-platform utility that provides convenient work with WebDAV-servers right from your console. In addition to full implementations of methods from webdav API, also added methods content sync local and remote directories.

Authentication

  • Basic authentication
$ wdc login https://wedbav.server.ru -p http://127.0.0.1:8080
webdav_login: w_login
webdav_password: w_password
proxy_login: p_login
proxy_password: p_password
success
  • Authorize the application using OAuth token*
$ wdc login https://wedbav.server.ru -p http://127.0.0.1:8080 --token xxxxxxxxxxxxxxxxxx
proxy_login: p_login
proxy_password: p_password
success

There are also additional keys --root[-r], --cert-path[-c] and --key-path[-k].

Utility

$ wdc check
success
$ wdc check file1
not success
$ wdc free
245234120344
$ wdc ls dir1
file1
...
fileN
$ wdc mkdir dir2
$ wdc copy dir1/file1 -t dir2/file1
$ wdc move dir2/file1 -t dir2/file2
$ wdc download dir1/file1 -t ~/Downloads/file1
$ wdc download dir1/ -t ~/Downloads/dir1/
$ wdc upload dir2/file2 -f ~/Documents/file1
$ wdc upload dir2/ -f ~/Documents/
$ wdc publish di2/file2
https://yadi.sk/i/vWtTUcBucAc6k
$ wdc unpublish dir2/file2
$ wdc pull dir1/ -t ~/Documents/dir1/
$ wdc push dir1/ -f ~/Documents/dir1/
$ wdc info dir1/file1
{'name': 'file1', 'modified': 'Thu, 23 Oct 2014 16:16:37 GMT',
'size': '3460064', 'created': '2014-10-23T16:16:37Z'}

WebDAV-server

The most popular cloud-based repositories that support the Protocol WebDAV can be attributed Yandex.Drive, Dropbox, Google Drive, Box and 4shared. Access to data repositories, operating with access to the Internet. If necessary local locations and cloud storage, you can deploy your own WebDAV-server.

Local WebDAV-server

To deploy a local WebDAV server, using Docker containers quite easily and quickly. To see an example of a local deploymentWebDAV servers can be on the project webdav-server-docker.

Supported methods

Servers free info list mkdir clean copy move download upload
Yandex.Disk + + + + + + + + +
Dropbox - + + + + + + + +
Google Drive - + + + + - - + +
Box + + + + + + + + +
4shared - + + + + - - + +
Webdavserver - + + + + - - + +

Publish and unpublish methods supports only Yandex.Disk.

Configuring connections

To work with cloud storage Dropbox and Google Drive via the WebDAV Protocol, you must use a WebDAV-server DropDAV and DAV-pocket, respectively.

A list of settings for WebDAV servers:

webdav-servers:
- yandex
    hostname: https://webdav.yandex.ru
    login:    #login_for_yandex
    password: #pass_for_yandex
- dropbox 
    hostname: https://dav.dropdav.com
    login:    #login_for dropdav
    password: #pass_for_dropdav
- google
    hostname: https://dav-pocket.appspot.com
    root:     docso
    login:    #login_for_dav-pocket
    password: #pass_for_dav-pocket
- box
    hostname: https://dav.box.com
    root:     dav
    login:    #login_for_box
    password: #pass_for_box
- 4shared
    hostname: https://webdav.4shared.com
    login:    #login_for_4shared
    password: #pass_for_4shared

Autocompletion

For macOS, or older Unix systems you need to update bash.

$ brew install bash
$ chsh
$ brew install bash-completion

Autocompletion can be enabled globally

$ sudo activate-global-python-argcomplete

or locally

#.bashrc
eval "$(register-python-argcomplete wdc)"

webdav-client-python's People

Contributors

cesterlizi avatar designerror avatar hongquan avatar simplydesigner 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

webdav-client-python's Issues

lxml is not needed

Hi there,
the current package seem to require lxml, yet this module only uses the etree interface, which has a builtin C and Python implementation (xml.etree.cElementTree and xml.etree.ElementTree). As such, you could make lxml an optional dependency, which would make the webdav module way easier to setup on machines without compilers as well as Python implementations other than CPython.

The fix is straightforward: in webdav/client.py, replace

import lxml.etree as etree

with

try:
    from lxml import etree
except ImportError:
    try:
        from xml.etree import cElementTree as etree
    except ImportError:
        from xml.etree import ElementTree as etree

this way, the lxml implementation is used if available; otherwise, the C implementation is used; if it's not available, the plain Python implementation is used. Then, you could remove lxml from the hard dependencies !

owncloud webdav

Hi,
I tried your client for owncloud
upload_sync worked smoothly but download_sync ...
I gave the output. What could cause this

c.download_sync(remote_path="http://localhost/owncloud/remote.php/webdav/sync/", local_path="/home/kerim/sync")


Traceback (most recent call last):
File "", line 1, in
File "/home/kerim/.local/lib/python2.7/site-packages/webdav/client.py", line 417, in download_sync
self.download(local_path=local_path, remote_path=remote_path)
File "/home/kerim/.local/lib/python2.7/site-packages/webdav/client.py", line 358, in download
if self.is_dir(urn.path()):
File "/home/kerim/.local/lib/python2.7/site-packages/webdav/client.py", line 845, in is_dir
raise RemoteResourceNotFound(remote_path)
webdav.exceptions.RemoteResourceNotFound: Remote resource: /http:/localhost/owncloud/remote.php/webdav/sync/ not found


Being able to disable SSL verification or to specify a CA file

I need to be able to specify a local CA file when connecting to a HTTPS webdav server because we use a local Certification Authority. I don't know how to do that with this webdav library. Is it ever possible?.

I don't want to disable TLS verification but would be nice to have the choice too.

Thanks.

list() problem

I connect to box.com and list my resourses and I got list:
['dav/', 'dir1/', 'Tulips.jpg']

When I list 'dir1' client.list("dir1/") I got an error:

Traceback (most recent call last):
  File "./webdav_client_2.py", line 17, in <module>
    client.mkdir("dir1/")
  File "/usr/local/lib/python2.7/dist-packages/webdav/client.py", line 307, in mkdir
    raise RemoteParentNotFound(directory_urn.path())
webdav.exceptions.RemoteParentNotFound: Remote parent for: /dir1/ not found

How to list directories from DAV?

disable/enable pycurl transfer information

Would you like to add parameter in options to disable/enable pycurl transfer information, like that:

% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 238k 0 0 100 238k 0 99245 0:00:02 0:00:02 --:--:-- 99251

It is visible when download/upload function is used.

`wc.check` throw `MethodNotSupported` if path doesn't exist (yandex webdav)

Hello. Thanks for library, found it useful.

I've tried to use check method to clarify, exists file on my remote disk or not and got MethodNotSupported. After some investigation, I realized, that it happens in next cases:

# Let's all dirs and files exists
wc.check('/root/test_folder/test.txt')  # True
# Let's root and test_folder exists
wc.check('/root/test_folder/test.txt')  # False
# Only root folder exists
wc.check('/root/test_folder/test.txt')  # raise etree.XMLSyntaxError, because
# in that case yandex.disk respond with 404 HTTP status and `parse` method failed

Is it expected behavior?

utf-8 and spaces in filename

Hi,

I played a bit with your webdavclient library and it seems great. But I have two issues. Spaces and UTF-8 characters. Here is a trace with an error:

>>> import webdav.client as wc
>>> options = {"webdav_hostname":"https://dav.box.com", "webdav_login":"login", "webdav_password":"password"}
>>> client = wc.Client(options)
>>> client.list()
['dav/', 'Uploads must go into the dav directory.txt']
>>> client.list("dav/")
['dav/', 'cv-en.pdf', 'winn\xc3\xa9.bmp']
>>> client.info("dav/cv-en.pdf")
{'created': '2014-12-24T12:25:11Z', 'name': None, 'modified': 'Wed, 24 Dec 2014 12:25:11 GMT', 'size': '132550'}
>>> client.info("dav/winn\xc3\xa9.bmp")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/louis/Code/Envs/py27/local/lib/python2.7/site-packages/webdav/client.py", line 840, in info
    return parse(response, path)
  File "/home/louis/Code/Envs/py27/local/lib/python2.7/site-packages/webdav/client.py", line 808, in parse
    raise RemoteResourceNotFound(path)
webdav.exceptions.RemoteResourceNotFound: Remote resource: /dav/winné.bmp not found

I’m not able to get informations or to download the file winné.bmp with your library. I have exactly the same issue if there is a space in the file name. I tried to quote the filename (with the function in urllib), but it still does not work.

Am I doing something wrong? Is it an issue with the library?

client.check works but client.info can't find the remote file

The following code is working

  client.check(remote_path) #returns true (file is present)
  client.list() #lists all files correctly

but the following statements won't work

    print(client.info("0000249385.zip").size)
    print(client.info(remote_path))

The whole code:

def downloadFile(id):
    remote_path = id + ".zip"
    local_path = "C:/User/i/Desktop/" + id + ".zip"
    
    import webdav.client as wc

    options = {
     'webdav_hostname': "https://server.com:8081/Testfolder/",
     'webdav_login':    "user",
     'webdav_password': 'password'
    }
    client = wc.Client(options)
    client.webdav.is_valid()
    client.default_options['SSL_VERIFYPEER'] = False 
    client.default_options['SSL_VERIFYHOST'] = False
    #this statement list all files correctly
    print(client.list())
    #returns true (as expected)
    print(client.check(remote_path))

The error from the Python IDLE console

===== RESTART: C:/Users/i/AppData/Local/Programs/Python/Python36/test.py =====
['Testfolder/', '@Recycle/', '0000249385.zip', 'index.txt']
Traceback (most recent call last):
  File "C:/Users/i/AppData/Local/Programs/Python/Python36/test.py", line 62, in <module>
    downloadFile("0000249385")
  File "C:/Users/i/AppData/Local/Programs/Python/Python36/test.py", line 21, in downloadFile
    print(client.info("0000249385.zip").size)
  File "C:\Users\i\AppData\Local\Programs\Python\Python36\lib\site-packages\webdav\client.py", line 803, in info
    return parse(response, path)
  File "C:\Users\i\AppData\Local\Programs\Python\Python36\lib\site-packages\webdav\client.py", line 776, in parse
    raise RemoteResourceNotFound(path)
webdav.exceptions.RemoteResourceNotFound: Remote resource: /0000249385.zip not found

etag support

Hi,

I suggest to add support for the etag field.
The change would be just a few lines in client.py:

find_attributes = {
    'created': ".//{DAV:}creationdate",
    'name': ".//{DAV:}displayname",
    'size': ".//{DAV:}getcontentlength",
    'modified': ".//{DAV:}getlastmodified",
    'etag': ".//{DAV:}getetag"  # new
}

I'd further add the following to remove the quotes around the etag (without this, it would be something link '"etag"'. I suggest to use the try / except - pattern as most servers are supporting the etag-field, and therefore this is approach is usually faster.

for (name, value) in find_attributes.items():
    info[name] = resp.findtext(value)

# new
try:
    info['etag'] = info['etag'][1:-1]  # remove quotes from etag
except KeyError:
    pass

Cheers
Tobias

box.com functions: copy, move

copy and move functions work for box.com but features table shows that they are unavailable for that service.
Would you like to update README.md.

list shows containing directory too, why?

Hi, just wondering if this intended behaviour.

when I use client.list('folder'), it not only retrieves the contents (files, subfolders) of this folder but also the containing folder itself as

folder/

Is this supposed to be like that? IMHO this is misleading because it looks like another subfolder of "folder" (folder/folder is how I would interpret this)

Thanks a lot for a very great and useful piece of software by the way!!! :-)
all the best
Jojo

after webdavclient, not work smtplib

smtplib raise exception
self = _SSLContext.new(cls, protocol)
ssl.SSLError: [SSL: UNABLE_TO_LOAD_SSL2_MD5_ROUTINES] unknown error (_ssl.c:2683)

pycurl verison error

Getting this error: ImportError: pycurl: libcurl link-time version (7.49.1) is older than compile-time version (7.51.0)

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.