├── .coveragerc ├── .functests ├── .gitignore ├── .gitreview ├── .mailmap ├── .manpages ├── .stestr.conf ├── .unittests ├── .zuul.yaml ├── AUTHORS ├── CONTRIBUTING.rst ├── ChangeLog ├── LICENSE ├── MANIFEST.in ├── README.rst ├── bin └── swift ├── doc ├── Makefile ├── manpages │ └── swift.1 ├── requirements.txt └── source │ ├── _static │ └── .gitignore │ ├── _templates │ └── .empty │ ├── cli │ └── index.rst │ ├── client-api.rst │ ├── conf.py │ ├── contributor │ └── contributing.rst │ ├── index.rst │ ├── introduction.rst │ ├── service-api.rst │ └── swiftclient.rst ├── examples ├── capabilities.py ├── copy.py ├── delete.py ├── download.py ├── list.py ├── post.py ├── stat.py └── upload.py ├── pyproject.toml ├── releasenotes ├── notes │ ├── 310-notes-03040158a8683dd8.yaml │ ├── 320_notes-bb367dba1053d34c.yaml │ ├── 340_notes-1777780bbfdb4d96.yaml │ ├── 350_notes-ad0ae19704b2eb88.yaml │ ├── 360_notes-1ec385df13a3a735.yaml │ ├── 361_notes-59e020e68bcdd709.yaml │ ├── 3_8_0_release-bd867fbdb8c895d3.yaml │ ├── 3_8_1_release-cb5648c3ae69bde1.yaml │ ├── 3_9_0_release-3c293d277f14ec22.yaml │ ├── 4_3_0_release.yaml │ ├── 4_4_0_release-d731bab5982c160b.yaml │ ├── 4_5_0_release-b315d25b889293f2.yaml │ ├── 4_6_0_release-92e466eb55b80225.yaml │ └── 4_8_0_release-41ba0852981191c3.yaml └── source │ ├── 2023.1.rst │ ├── 2023.2.rst │ ├── 2024.1.rst │ ├── 2024.2.rst │ ├── 2025.1.rst │ ├── conf.py │ ├── current.rst │ ├── index.rst │ ├── newton.rst │ ├── ocata.rst │ ├── pike.rst │ ├── queens.rst │ ├── rocky.rst │ ├── stein.rst │ ├── train.rst │ ├── ussuri.rst │ ├── victoria.rst │ ├── wallaby.rst │ ├── xena.rst │ ├── yoga.rst │ └── zed.rst ├── requirements.txt ├── run_tests.sh ├── setup.cfg ├── setup.py ├── swiftclient ├── __init__.py ├── authv1.py ├── client.py ├── command_helpers.py ├── exceptions.py ├── multithreading.py ├── requests_compat.py ├── service.py ├── shell.py ├── utils.py └── version.py ├── test-requirements.txt ├── test ├── __init__.py ├── functional │ ├── __init__.py │ ├── test_openstacksdk.py │ └── test_swiftclient.py ├── sample.conf └── unit │ ├── __init__.py │ ├── test_authv1.py │ ├── test_command_helpers.py │ ├── test_multithreading.py │ ├── test_service.py │ ├── test_shell.py │ ├── test_swiftclient.py │ ├── test_utils.py │ └── utils.py ├── tools └── swift.bash_completion └── tox.ini /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | branch = True 3 | source = swiftclient 4 | 5 | [report] 6 | ignore_errors = True 7 | -------------------------------------------------------------------------------- /.functests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | export OS_TEST_PATH='test.functional' 5 | export PYTHON='coverage run --source swiftclient --parallel-mode' 6 | stestr run --concurrency=1 7 | 8 | RET=$? 9 | coverage combine 10 | coverage html -d cover 11 | coverage xml -o cover/coverage.xml 12 | coverage report -m 13 | rm -f .coverage 14 | exit $RET 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.sw? 2 | dist/ 3 | .tox 4 | *.egg 5 | *.egg-info 6 | *.py[co] 7 | .DS_Store 8 | *.log 9 | .testrepository 10 | .stestr/ 11 | subunit.log 12 | build 13 | swiftclient/versioninfo 14 | .autogenerated 15 | .coverage 16 | cover/ 17 | coverage.xml 18 | doc/build 19 | doc/source/api/ 20 | .idea 21 | -------------------------------------------------------------------------------- /.gitreview: -------------------------------------------------------------------------------- 1 | [gerrit] 2 | host=review.opendev.org 3 | port=29418 4 | project=openstack/python-swiftclient.git 5 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Greg Holt gholt 2 | Greg Holt gholt 3 | Greg Holt gholt 4 | Greg Holt gholt 5 | Greg Holt 6 | Greg Holt 7 | John Dickinson 8 | Michael Barton 9 | Michael Barton 10 | Michael Barton Mike Barton 11 | Clay Gerrard 12 | Clay Gerrard 13 | Clay Gerrard 14 | Clay Gerrard clayg 15 | David Goetz 16 | David Goetz 17 | Anne Gentle 18 | Anne Gentle annegentle 19 | Fujita Tomonori 20 | Greg Lange 21 | Greg Lange 22 | Chmouel Boudjnah 23 | Gaurav B. Gangalwar gaurav@gluster.com <> 24 | Joe Arnold 25 | Kapil Thangavelu kapil.foss@gmail.com <> 26 | Samuel Merritt 27 | Morita Kazutaka 28 | Zhongyue Luo 29 | Russ Nelson 30 | Marcelo Martins 31 | Andrew Clay Shafer 32 | Soren Hansen 33 | Soren Hansen 34 | Ye Jia Xu monsterxx03 35 | Victor Rodionov 36 | Florian Hines 37 | Jay Payne 38 | Doug Weimer 39 | Li Riqiang lrqrun 40 | Cory Wright 41 | Julien Danjou 42 | David Hadas 43 | Yaguang Wang ywang19 44 | Liu Siqi dk647 45 | James E. Blair 46 | Kun Huang 47 | Michael Shuler 48 | Ilya Kharin 49 | Dmitry Ukov Ukov Dmitry 50 | Tom Fifield Tom Fifield 51 | Sascha Peilicke Sascha Peilicke 52 | Zhenguo Niu 53 | Peter Portante 54 | Christian Schwede 55 | Christian Schwede 56 | Constantine Peresypkin 57 | Madhuri Kumari madhuri 58 | Morgan Fainberg 59 | Hua Zhang 60 | Yummy Bian 61 | Alistair Coles 62 | Alistair Coles 63 | Tong Li 64 | Paul Luse 65 | Yuan Zhou 66 | Jola Mirecka 67 | Ning Zhang 68 | Mauro Stettler 69 | Pawel Palucki 70 | Guang Yee 71 | Jing Liuqing 72 | Lorcan Browne 73 | Eohyung Lee 74 | Harshit Chitalia 75 | Richard Hawkins 76 | Sarvesh Ranjan 77 | Minwoo Bae Minwoo B 78 | Jaivish Kothari 79 | Michael Matur 80 | Kazuhiro Miyahara 81 | Alexandra Settle 82 | Mark Seger 83 | Donagh McCabe 84 | Stuart McLaren 85 | Alexis Lee 86 | Stanislaw Pitucha 87 | Mahati Chamarthy 88 | Peter Lisak 89 | Doug Hellmann 90 | Ondrej Novy 91 | James Nzomo 92 | Alessandro Pilotti 93 | Marek Kaleta 94 | Andreas Jaeger 95 | Shashi Kant 96 | Nandini Tata 97 | Flavio Percoco 98 | Timur Alperovich 99 | Thiago da Silva 100 | DavHau 101 | -------------------------------------------------------------------------------- /.manpages: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | RET=0 4 | for MAN in doc/manpages/* ; do 5 | OUTPUT=$(LC_ALL=en_US.UTF-8 MANROFFSEQ='' MANWIDTH=80 man --warnings -E UTF-8 -l \ 6 | -Tutf8 -Z "$MAN" 2>&1 >/dev/null) 7 | if [ -n "$OUTPUT" ] ; then 8 | RET=1 9 | echo "$MAN:" 10 | echo "$OUTPUT" 11 | fi 12 | done 13 | 14 | if [ "$RET" -eq "0" ] ; then 15 | echo "All manpages are fine" 16 | fi 17 | 18 | exit "$RET" 19 | -------------------------------------------------------------------------------- /.stestr.conf: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | test_path=${OS_TEST_PATH:-./test/unit} 3 | top_dir=./ 4 | 5 | -------------------------------------------------------------------------------- /.unittests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | python setup.py testr --coverage --testr-args="test.unit" 5 | RET=$? 6 | coverage report -m 7 | rm -f .coverage 8 | exit $RET 9 | -------------------------------------------------------------------------------- /.zuul.yaml: -------------------------------------------------------------------------------- 1 | - job: 2 | name: swiftclient-swift-functional 3 | parent: swift-dsvm-functional 4 | description: | 5 | Run swift's functional tests with python-swiftclient 6 | installed from source instead as package from PyPI. 7 | # Ensure that we install python-swiftclient from git and 8 | # do not install from pypi. This is needed since the parent 9 | # job sets zuul_work_dir to the swift directory and uses tox 10 | # for installation. 11 | required-projects: 12 | - opendev.org/openstack/python-swiftclient 13 | vars: 14 | # New tox keeps breaking things as of 2023-01 15 | ensure_tox_version: '<4' 16 | 17 | - job: 18 | name: swiftclient-functional 19 | parent: swift-dsvm-functional 20 | description: | 21 | Run functional tests of python-swiftclient with 22 | python-swiftclient installed from source instead as package from 23 | PyPI. 24 | required-projects: 25 | - opendev.org/openstack/python-swiftclient 26 | vars: 27 | # Override value from parent job to use swiftclient tests 28 | zuul_work_dir: "{{ zuul.projects['opendev.org/openstack/python-swiftclient'].src_dir }}" 29 | # swift can use different tox env names 30 | tox_envlist: func 31 | 32 | - project: 33 | templates: 34 | - check-requirements 35 | - lib-forward-testing-python3 36 | - openstack-python3-jobs 37 | - publish-openstack-docs-pti 38 | - release-notes-jobs-python3 39 | experimental: 40 | # on-demand pipeline used to test older (but still supported) versions of python, 41 | # as well as intermediate releases that the openstack-python3-jobs might skip 42 | jobs: 43 | - openstack-tox-py37 44 | - openstack-tox-py38 45 | - openstack-tox-py39 46 | - openstack-tox-py311 47 | check: 48 | jobs: 49 | - swiftclient-functional: 50 | irrelevant-files: &functest-irrelevant-files 51 | - ^(doc|releasenotes)/.*$ 52 | - ^test/unit/.*$ 53 | - ^(.gitreview|.mailmap|AUTHORS|ChangeLog|.*\.rst)$ 54 | - swiftclient-swift-functional: 55 | irrelevant-files: *functest-irrelevant-files 56 | - tempest-full-py3: 57 | irrelevant-files: *functest-irrelevant-files 58 | - openstack-tox-py313: 59 | voting: true 60 | gate: 61 | jobs: 62 | - swiftclient-swift-functional 63 | - swiftclient-functional 64 | - openstack-tox-py313: 65 | voting: true 66 | post: 67 | jobs: 68 | - openstack-tox-cover 69 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Aarni Koskela (akx@iki.fi) 2 | Alessandro Pilotti (ap@pilotti.it) 3 | Alex Gaynor (alex.gaynor@gmail.com) 4 | Alex Schultz (aschultz@redhat.com) 5 | Alexandra Settle (alexandra.settle@rackspace.com) 6 | Alexis Lee (lxsli@hpe.com) 7 | Alistair Coles (alistairncoles@gmail.com) 8 | Andreas Jaeger (aj@suse.de) 9 | Andrew Welleck (awellec@us.ibm.com) 10 | Andy McCrae (andy.mccrae@gmail.com) 11 | Anh Tran (anhtt@vn.fujitsu.com) 12 | Anne Gentle (anne@openstack.org) 13 | Ben McCann (ben@benmccann.com) 14 | Cedric Brandily (zzelle@gmail.com) 15 | Chaozhe.Chen (chaozhe.chen@easystack.cn) 16 | Charles Hsu (charles0126@gmail.com) 17 | Chen (dstbtgagt@foxmail.com) 18 | Cheng Li (shcli@cn.ibm.com) 19 | Chmouel Boudjnah (chmouel@enovance.com) 20 | Chris Buccella (chris.buccella@antallagon.com) 21 | Christian Berendt (berendt@b1-systems.de) 22 | Christian Schwede (cschwede@redhat.com) 23 | Christopher Bartz (bartz@dkrz.de) 24 | Chuck Short (chuck.short@canonical.com) 25 | Clark Boylan (clark.boylan@gmail.com) 26 | Claudiu Belu (cbelu@cloudbasesolutions.com) 27 | Clay Gerrard (clay.gerrard@gmail.com) 28 | Clint Byrum (clint@fewbar.com) 29 | Corey Bryant (corey.bryant@canonical.com) 30 | Dan Prince (dprince@redhat.com) 31 | Daniel Wakefield (daniel.wakefield@hp.com) 32 | Darrell Bishop (darrell@swiftstack.com) 33 | DavHau (hsngrmpf@gmail.com) 34 | David Goetz (david.goetz@rackspace.com) 35 | David Kranz (david.kranz@qrclab.com) 36 | David Shrewsbury (shrewsbury.dave@gmail.com) 37 | Davide Guerri (davide.guerri@hp.com) 38 | Dean Troyer (dtroyer@gmail.com) 39 | Dirk Mueller (dirk@dmllr.de) 40 | Donagh McCabe (donagh.mccabe@hpe.com) 41 | Doug Hellmann (doug@doughellmann.com) 42 | EdLeafe (ed@leafe.com) 43 | Erik Olof Gunnar Andersson (eandersson@blizzard.com) 44 | Fabien Boucher (fabien.boucher@enovance.com) 45 | Feng Liu (mefengliu23@gmail.com) 46 | Flavio Percoco (flaper87@gmail.com) 47 | Florent Flament (florent.flament-ext@cloudwatt.com) 48 | fuzihao (fuzihao@inspur.com) 49 | Ghanshyam Mann (gmann@ghanshyammann.com) 50 | Greg Holt (gholt@rackspace.com) 51 | Greg Lange (greglange@gmail.com) 52 | groqez (groqez@yopmail.net) 53 | Hangdong Zhang (hdzhang@fiberhome.com) 54 | Hemanth Makkapati (hemanth.makkapati@mailtrust.com) 55 | hgangwx (hgangwx@cn.ibm.com) 56 | Hirokazu Sakata (h.sakata@staff.east.ntt.co.jp) 57 | Hiroshi Miura (miurahr@nttdata.co.jp) 58 | howardlee (lihongweibj@inspur.com) 59 | Hu Bing (hubingsh@cn.ibm.com) 60 | Ian Cordasco (ian.cordasco@rackspace.com) 61 | Ivan Kolodyazhny (e0ne@e0ne.info) 62 | jacky06 (zhang.min@99cloud.net) 63 | Jaivish Kothari (jaivish.kothari@nectechnologies.in) 64 | Jakub Krajcovic (jakub.krajcovic@gmail.com) 65 | James Nzomo (james@tdt.rocks) 66 | Jamie Lennox (jamielennox@gmail.com) 67 | Jeremy Stanley (fungi@yuggoth.org) 68 | Ji-Wei (ji.wei3@zte.com.cn) 69 | Jian Zhang (jian.zhang@intel.com) 70 | Jing Liuqing (jing.liuqing@99cloud.net) 71 | jinyuanliu (liujinyuan@inspur.com) 72 | Jiří Suchomel (jsuchome@suse.cz) 73 | Joel Wright (joel.wright@sohonet.com) 74 | jonasdlindner (jonaslindner55@gmail.com) 75 | John Dickinson (me@not.mn) 76 | Jola Mirecka (jola.mirecka@hp.com) 77 | Josh Gachnang (josh@pcsforeducation.com) 78 | Juan J. Martinez (juan@memset.com) 79 | Jude Job (judeopenstack@gmail.com) 80 | Julien Danjou (julien@danjou.info) 81 | kangyufei (kangyf@inspur.com) 82 | Kazufumi Noto (noto.kazufumi@gmail.com) 83 | Kota Tsuyuzaki (tsuyuzaki.kota@lab.ntt.co.jp) 84 | Kun Huang (gareth@unitedstack.com) 85 | Leah Klearman (lklrmn@gmail.com) 86 | Li Riqiang (lrqrun@gmail.com) 87 | lingyongxu (lyxu@fiberhome.com) 88 | liuyamin (liuyamin@fiberhome.com) 89 | Luis de Bethencourt (luis@debethencourt.com) 90 | M V P Nitesh (m.nitesh@nectechnologies.in) 91 | Mahati Chamarthy (mahati.chamarthy@gmail.com) 92 | Marek Kaleta (marek.kaleta@firma.seznam.cz) 93 | Mark Seger (mark.seger@hpe.com) 94 | Mark Washenberger (mark.washenberger@rackspace.com) 95 | Martin Geisler (martin@geisler.net) 96 | Matthew Oliver (matt@oliver.net.au) 97 | Matthieu Huin (mhu@enovance.com) 98 | Meuh (fabien+swift@bagard.xyz) 99 | Mike Widman (mwidman@endurancewindpower.com) 100 | Min Min Ren (rminmin@cn.ibm.com) 101 | mmcardle (mark.mcardle@sohonet.com) 102 | Mohit Motiani (mohit.motiani@intel.com) 103 | Monty Taylor (mordred@inaugust.com) 104 | Nandini Tata (nandini.tata@intel.com) 105 | Nelson Marcos (nelsonmarcos@gmail.com) 106 | Nguyen Hai (nguyentrihai93@gmail.com) 107 | Nguyen Hai Truong (truongnh@vn.fujitsu.com) 108 | Nguyen Hung Phuong (phuongnh@vn.fujitsu.com) 109 | Nick Craig-Wood (nick@craig-wood.com) 110 | Ondrej Novy (ondrej.novy@firma.seznam.cz) 111 | Pallavi (pallavi.s@nectechnologies.in) 112 | PAPAMICA (mickael@papamica.com) 113 | Pavel Abalikhin (anpavl@gmail.com) 114 | Paul Belanger (pabelanger@redhat.com) 115 | Paulo Ewerton (pauloewerton@lsd.ufcg.edu.br) 116 | Pawel Tetera (ptetera@redhat.com) 117 | pengyuesheng (pengyuesheng@gohighsec.com) 118 | Pete Zaitcev (zaitcev@kotori.zaitcev.us) 119 | Peter Lisak (peter.lisak@firma.seznam.cz) 120 | Petr Kovar (pkovar@redhat.com) 121 | Pradeep Kumar Singh (pradeep.singh@nectechnologies.in) 122 | Pratik Mallya (pratik.mallya@gmail.com) 123 | qingszhao (zhao.daqing@99cloud.net) 124 | Qiu Yu (qiuyu@ebaysf.com) 125 | Ray Chen (oldsharp@163.com) 126 | ricolin (rico.l@inwinstack.com) 127 | Romain Hardouin (romain_hardouin@yahoo.fr) 128 | Sahid Orentino Ferdjaoui (sahid.ferdjaoui@cloudwatt.com) 129 | SaiKiran (saikiranveeravarapu@gmail.com) 130 | Sam Morrison (sorrison@gmail.com) 131 | Samuel Merritt (sam@swiftstack.com) 132 | Sean Dague (sean@dague.net) 133 | Sean McGinnis (sean.mcginnis@gmail.com) 134 | Sébastien Blaisot (sebastien@blaisot.org) 135 | Sergey Gotliv (sgotliv@redhat.com) 136 | Sergio Cazzolato (sergio.j.cazzolato@intel.com) 137 | Shane Wang (shane.wang@intel.com) 138 | shangxiaobj (shangxiaobj@inspur.com) 139 | Shashi Kant (shashi.kant@nectechnologies.in) 140 | Shashirekha Gundur (shashirekha.j.gundur@intel.com) 141 | shu-mutou (shu-mutou@rf.jp.nec.com) 142 | Stanislav Vitkovskiy (stas.vitkovsky@gmail.com) 143 | Stanislaw Pitucha (stanislaw.pitucha@hpe.com) 144 | Stephen Finucane (stephenfin@redhat.com) 145 | Steve Kowalik (steven@wedontsleep.org) 146 | Steve Martinelli (stevemar@ca.ibm.com) 147 | Steven Hardy (shardy@redhat.com) 148 | Stuart McLaren (stuart.mclaren@hpe.com) 149 | sunjia (sunjia@inspur.com) 150 | Sushil Kumar (sushil.kumar2@globallogic.com) 151 | tanlin (lin.tan@intel.com) 152 | Taurus Cheung (Taurus.Cheung@harmonicinc.com) 153 | Takashi Kajinami (tkajinam@redhat.com) 154 | Takashi Natsume (takanattie@gmail.com) 155 | TheSriram (sriram@klusterkloud.com) 156 | Thiago da Silva (thiagodasilva@gmail.com) 157 | Thomas Goirand (thomas@goirand.fr) 158 | Tihomir Trifonov (t.trifonov@gmail.com) 159 | Tim Burke (tim.burke@gmail.com) 160 | Timur Alperovich (timuralp@swiftstack.com) 161 | Tong Li (litong01@us.ibm.com) 162 | Tony Breeds (tony@bakeyournoodle.com) 163 | Tovin Seven (vinhnt@vn.fujitsu.com) 164 | Tristan Cacqueray (tristan.cacqueray@enovance.com) 165 | Vasyl Khomenko (vasiliyk@yahoo-inc.com) 166 | venkatamahesh (venkatamaheshkotha@gmail.com) 167 | Victor Stinner (victor.stinner@enovance.com) 168 | Vitaly Gridnev (vgridnev@mirantis.com) 169 | Vu Cong Tuan (tuanvc@vn.fujitsu.com) 170 | wangqi (wang.qi@99cloud.net) 171 | wangxiyuan (wangxiyuan@huawei.com) 172 | wangzhenyu (wangzy@fiberhome.com) 173 | Wu Wenxiang (wu.wenxiang@99cloud.net) 174 | wu.chunyang (wu.chunyang@99cloud.net) 175 | wu.shiming (wushiming@yovole.com) 176 | Yan Xiao (yanxiao@nvidia.com) 177 | YangLei (yanglyy@cn.ibm.com) 178 | yangxurong (yangxurong@huawei.com) 179 | yangyawei (yangyawei@inspur.com) 180 | You Yamagata (bi.yamagata@gmail.com) 181 | Yuan Zhou (yuan.zhou@intel.com) 182 | Yushiro FURUKAWA (y.furukawa_2@jp.fujitsu.com) 183 | yuxcer (yuxcer@126.com) 184 | yuyafei (yu.yafei@zte.com.cn) 185 | YUZAWA Takahiko (yuzawataka@intellilink.co.jp) 186 | Zack M. Davis (zdavis@swiftstack.com) 187 | zhang-jinnan (ben.os@99cloud.net) 188 | zhangboye (zhangboye@inspur.com) 189 | zhangyanxian (zhangyanxianmail@163.com) 190 | zheng yin (yin.zheng@easystack.cn) 191 | Zhenguo Niu (zhenguo@unitedstack.com) 192 | ZhijunWei (wzj334965317@outlook.com) 193 | zhubx007 (zhu.boxiang@99cloud.net) 194 | -------------------------------------------------------------------------------- /CONTRIBUTING.rst: -------------------------------------------------------------------------------- 1 | The source repository for this project can be found at: 2 | 3 | https://opendev.org/openstack/python-swiftclient 4 | 5 | Pull requests submitted through GitHub are not monitored. 6 | 7 | To start contributing to OpenStack, follow the steps in the contribution guide 8 | to set up and use Gerrit: 9 | 10 | https://docs.openstack.org/contributors/code-and-documentation/quick-start.html 11 | 12 | Bugs should be filed on Launchpad: 13 | 14 | https://bugs.launchpad.net/python-swiftclient 15 | 16 | For more specific information about contributing to this repository, see the 17 | swiftclient contributor guide: 18 | 19 | https://docs.openstack.org/python-swiftclient/latest/contributor/contributing.html 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include AUTHORS 2 | include ChangeLog 3 | include LICENSE 4 | include README.rst 5 | include run_tests.sh tox.ini 6 | recursive-include doc * 7 | recursive-include tests * 8 | recursive-include tools * 9 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Python bindings to the OpenStack Object Storage API 2 | =================================================== 3 | 4 | .. image:: https://img.shields.io/pypi/v/python-swiftclient.svg 5 | :target: https://pypi.org/project/python-swiftclient/ 6 | :alt: Latest Version 7 | 8 | This is a python client for the Swift API. There's a Python API (the 9 | ``swiftclient`` module), and a command-line script (``swift``). 10 | 11 | Development takes place via the usual OpenStack processes as outlined 12 | in the `OpenStack wiki`__. 13 | 14 | __ https://docs.openstack.org/infra/manual/developers.html 15 | 16 | This code is based on the original client previously included with 17 | `OpenStack's Swift`__. The python-swiftclient is licensed under the 18 | Apache License like the rest of OpenStack. 19 | 20 | __ https://github.com/openstack/swift 21 | 22 | * Free software: Apache license 23 | * `PyPI`_ - package installation 24 | * `Online Documentation`_ 25 | * `Launchpad project`_ - release management 26 | * `Bugs`_ - issue tracking 27 | * `Source`_ 28 | * `How to Contribute`_ 29 | * `Release Notes`_ 30 | 31 | .. _PyPI: https://pypi.org/project/python-swiftclient 32 | .. _Online Documentation: https://docs.openstack.org/python-swiftclient/latest/ 33 | .. _Launchpad project: https://launchpad.net/python-swiftclient 34 | .. _Bugs: https://bugs.launchpad.net/python-swiftclient 35 | .. _Source: https://opendev.org/openstack/python-swiftclient 36 | .. _How to Contribute: https://docs.openstack.org/infra/manual/developers.html 37 | .. _Release Notes: https://docs.openstack.org/releasenotes/python-swiftclient 38 | 39 | .. contents:: Contents: 40 | :local: 41 | -------------------------------------------------------------------------------- /bin/swift: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Copyright (c) 2014 Christian Schwede 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 13 | # implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | 18 | import sys 19 | 20 | from swiftclient.shell import main 21 | 22 | 23 | if __name__ == "__main__": 24 | sys.exit(main()) 25 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXSOURCE = source 8 | PAPER = 9 | BUILDDIR = build 10 | 11 | # Internal variables. 12 | PAPEROPT_a4 = -D latex_paper_size=a4 13 | PAPEROPT_letter = -D latex_paper_size=letter 14 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SPHINXSOURCE) 15 | 16 | .PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest 17 | 18 | help: 19 | @echo "Please use \`make ' where is one of" 20 | @echo " html to make standalone HTML files" 21 | @echo " dirhtml to make HTML files named index.html in directories" 22 | @echo " pickle to make pickle files" 23 | @echo " json to make JSON files" 24 | @echo " htmlhelp to make HTML files and a HTML help project" 25 | @echo " qthelp to make HTML files and a qthelp project" 26 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 27 | @echo " changes to make an overview of all changed/added/deprecated items" 28 | @echo " linkcheck to check all external links for integrity" 29 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 30 | 31 | clean: 32 | -rm -rf $(BUILDDIR)/* 33 | 34 | html: 35 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 36 | @echo 37 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 38 | 39 | dirhtml: 40 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 41 | @echo 42 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 43 | 44 | pickle: 45 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 46 | @echo 47 | @echo "Build finished; now you can process the pickle files." 48 | 49 | json: 50 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 51 | @echo 52 | @echo "Build finished; now you can process the JSON files." 53 | 54 | htmlhelp: 55 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 56 | @echo 57 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 58 | ".hhp project file in $(BUILDDIR)/htmlhelp." 59 | 60 | qthelp: 61 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 62 | @echo 63 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 64 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 65 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/python-swiftclient.qhcp" 66 | @echo "To view the help file:" 67 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/python-swiftclient.qhc" 68 | 69 | latex: 70 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 71 | @echo 72 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 73 | @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ 74 | "run these through (pdf)latex." 75 | 76 | changes: 77 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 78 | @echo 79 | @echo "The overview file is in $(BUILDDIR)/changes." 80 | 81 | linkcheck: 82 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 83 | @echo 84 | @echo "Link check complete; look for any errors in the above output " \ 85 | "or in $(BUILDDIR)/linkcheck/output.txt." 86 | 87 | doctest: 88 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 89 | @echo "Testing of doctests in the sources finished, look at the " \ 90 | "results in $(BUILDDIR)/doctest/output.txt." 91 | -------------------------------------------------------------------------------- /doc/manpages/swift.1: -------------------------------------------------------------------------------- 1 | .\" 2 | .\" Author: Joao Marcelo Martins or 3 | .\" Copyright (c) 2010-2011 OpenStack Foundation. 4 | .\" 5 | .\" Licensed under the Apache License, Version 2.0 (the "License"); 6 | .\" you may not use this file except in compliance with the License. 7 | .\" You may obtain a copy of the License at 8 | .\" 9 | .\" http://www.apache.org/licenses/LICENSE-2.0 10 | .\" 11 | .\" Unless required by applicable law or agreed to in writing, software 12 | .\" distributed under the License is distributed on an "AS IS" BASIS, 13 | .\" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 14 | .\" implied. 15 | .\" See the License for the specific language governing permissions and 16 | .\" limitations under the License. 17 | .\" 18 | .TH swift 1 "8/26/2011" "Linux" "OpenStack Swift" 19 | 20 | .SH NAME 21 | .LP 22 | .B swift 23 | \- OpenStack Swift client tool 24 | 25 | .SH SYNOPSIS 26 | .LP 27 | .B swift 28 | [options] [args] 29 | 30 | .SH DESCRIPTION 31 | .PP 32 | The \fBswift\fR tool is a command line utility for communicating with 33 | an OpenStack Object Storage (Swift) environment. It allows one to perform 34 | several types of operations. 35 | 36 | .SH COMMANDS 37 | .PP 38 | 39 | \fBstat\fR [\fIcommand-options\fR] [\fIcontainer\fR] [\fIobject\fR] 40 | .RS 4 41 | Displays information for the account, container, or object depending on the args given (if any). 42 | In verbose mode, the Storage URL and the authentication token are displayed 43 | as well. Option \-\-lh reports sizes in human readable format similar to ls \-lh. 44 | .RE 45 | 46 | \fBlist\fR [\fIcommand-options\fR] [\fIcontainer\fR] 47 | .RS 4 48 | Lists the containers for the account or the objects for a container. 49 | The \-p or \-\-prefix is an option that will only list items beginning 50 | with that prefix. The \-d or \-\-delimiter is option 51 | (for container listings only) that will roll up items with the given 52 | delimiter (see OpenStack Swift general documentation for what this means). 53 | 54 | The \-l or \-\-long and \-\-lh options provide more detail, similar to ls \-l and ls \-lh, the latter 55 | providing sizes in human readable format (eg 3K, 12M, etc). These latter 2 switches 56 | use more overhead to get those details, which is directly proportional to the number 57 | of container or objects being listed. With the \-t or \-\-total option they only report totals. 58 | .RE 59 | 60 | \fBupload\fR [\fIcommand-options\fR] container file_or_directory [\fIfile_or_directory\fR] [...] 61 | .RS 4 62 | Uploads to the given container the files and directories specified by the 63 | remaining args. The \-c or \-\-changed is an option that will only upload files 64 | that have changed since the last upload. The \-\-object\-name is 65 | an option that will upload file and name object to or upload dir 66 | and use as object prefix. If the file name is "-", reads the 67 | content from standard input. In this case, \-\-object\-name is required and no 68 | other files may be given. The \-S or \-\-segment\-size and 69 | \-\-leave\-segments and others are options as well (see swift upload \-\-help 70 | for more). 71 | .RE 72 | 73 | \fBpost\fR [\fIcommand-options\fR] [\fIcontainer\fR] [\fIobject\fR] 74 | .RS 4 75 | Updates meta information for the account, container, or object depending 76 | on the args given. If the container is not found, it will be created 77 | automatically; but this is not true for accounts and objects. Containers 78 | also allow the \-r (or \-\-read\-acl) and \-w (or \-\-write\-acl) options. The \-m 79 | or \-\-meta option is allowed on all and used to define the user meta data 80 | items to set in the form Name:Value. This option can be repeated. 81 | For more details and options see swift post \-\-help. 82 | \fBExample\fR: post \-m Color:Blue \-m Size:Large 83 | .RE 84 | 85 | \fBcopy\fR [\fIcommand-options\fR] \fIcontainer\fR \fIobject\fR 86 | .RS 4 87 | Copies an object to a new destination or adds user metadata to the object (current 88 | user metadata will be preserved, in contrast with the post command) depending 89 | on the args given. The \-\-destination option sets the destination in the form 90 | /container/object. If not set, the object will be copied onto itself which is useful 91 | for adding metadata. The \-M or \-\-fresh\-metadata option copies the object without 92 | the existing user metadata. The \-m or \-\-meta option is always allowed and is used 93 | to define the user metadata items to set in the form Name:Value (this option 94 | can be repeated). 95 | For more details and options see swift copy \-\-help. 96 | .RE 97 | 98 | \fBdownload\fR [\fIcommand-options\fR] [\fIcontainer\fR] [\fIobject\fR] [\fIobject\fR] [...] 99 | .RS 4 100 | Downloads everything in the account (with \-\-all), or everything in a 101 | container, or a list of objects depending on the args given. For a single 102 | object download, you may use the \-o [\-\-output] option to 103 | redirect the output to a specific file or if "-" then just redirect to stdout or 104 | with \-\-no-download actually not to write anything to disk. 105 | The \-\-ignore-checksum is an option that turns off checksum validation. 106 | You can specify optional headers with the repeatable cURL-like option 107 | \-H [\-\-header]. For more details and options see swift download \-\-help. 108 | The \-\-ignore\-mtime option ignores the x\-object\-meta\-mtime metadata entry 109 | on the object (if present) and instead creates the downloaded files with 110 | fresh atime and mtime values. 111 | .RE 112 | 113 | \fBdelete\fR [\fIcommand-options\fR] [\fIcontainer\fR] [\fIobject\fR] [\fIobject\fR] [...] 114 | .RS 4 115 | Deletes everything in the account (with \-\-all), or everything in a container, 116 | or all objects in a container that start with a given string (given by \-\-prefix), 117 | or a list of objects depending on the args given. Segments of manifest objects 118 | will be deleted as well, unless you specify the \-\-leave\-segments option. 119 | For more details and options see swift delete \-\-help. 120 | .RE 121 | 122 | \fBcapabilities\fR [\fIcommand-options\fR] [\fIproxy-url\fR] 123 | .RS 4 124 | Displays cluster capabilities. If the proxy-url option is not provided the 125 | storage-url retrieved after authentication is used as proxy-url. 126 | 127 | By default, the output includes the list of the activated Swift middlewares as 128 | well as relevant options for each one. Additionally the command displays 129 | relevant options for the Swift core. 130 | 131 | The \-\-json option will print a json representation of the cluster 132 | capabilities. This is typically more suitable for consumption by other 133 | programs, such as jq. 134 | 135 | \fBExample\fR: capabilities https://swift.example.com 136 | capabilities \-\-json 137 | .RE 138 | 139 | \fBtempurl\fR [\fIcommand-option\fR] \fImethod\fR \fItime\fR \fIpath\fR \fIkey\fR 140 | .RS 4 141 | Generates a temporary URL allowing unauthenticated access to the Swift object 142 | at the given path, using the given HTTP method, for the given time, 143 | using the given TempURL key. 144 | 145 | The time can be specified either as an integer 146 | denoting the amount of seconds the temporary URL is valid, or as an ISO 8601 147 | timestamp in one of following formats: Complete date: YYYY\-MM\-DD (eg 1997\-07\-16), 148 | complete date plus hours, minutes and seconds: YYYY\-MM\-DDThh:mm:ss 149 | (eg 1997\-07\-16T19:20:30) or complete date plus hours, minutes and seconds with 150 | UTC designator: YYYY\-MM\-DDThh:mm:ssZ (eg 1997\-07\-16T19:20:30Z). Be aware that 151 | if you do not use the latter format, the timestamp is generated using your locale 152 | timezone. If the first format is used, the time part used will equal to 00:00:00. 153 | 154 | With the \-\-prefix\-based option a 155 | prefix-based URL is generated. 156 | 157 | The option \-\-iso8601 provides ISO 8601 UTC timestamps 158 | instead of Unix timestamps inside the generated URL. 159 | 160 | If optional \-\-absolute argument is 161 | provided and the time argument is specified in seconds, the seconds are 162 | interpreted as a Unix timestamp at which the URL 163 | should expire. 164 | 165 | \fBExample\fR: tempurl GET $(date \-d "Jan 1 2016" +%s) 166 | /v1/AUTH_foo/bar_container/quux.md my_secret_tempurl_key \-\-absolute 167 | 168 | .RE 169 | 170 | \fBauth\fR 171 | .RS 4 172 | Display auth related authentication variables in shell friendly format. 173 | For examples see swift auth \-\-help. 174 | .RE 175 | 176 | .SH OPTIONS 177 | .PD 0 178 | .IP "--version Show program's version number and exit" 179 | .IP "-h, --help Show this (or any subcommand if after command) help message and exit" 180 | .IP "-s, --snet Use SERVICENET internal network" 181 | .IP "-v, --verbose Print more info" 182 | .IP "-q, --quiet Suppress status output" 183 | .IP "-A AUTH, --auth=AUTH URL for obtaining an auth token " 184 | .IP "-U USER, --user=USER User name for obtaining an auth token" 185 | .IP "-V 1|2, --auth-version=VERSION Authentication protocol version" 186 | .IP "-K KEY, --key=KEY Key for obtaining an auth token" 187 | .IP "--os-storage-url=URL Use this instead of URL returned from auth" 188 | .IP "--os-help Show all OpenStack authentication options" 189 | .PD 190 | .RS 4 191 | For more options see swift \-\-help and swift \-\-os\-help. 192 | .RE 193 | 194 | 195 | .SH EXAMPLE 196 | .PP 197 | swift \-A https://127.0.0.1:443/auth/v1.0 \-U swiftops:swiftops \-K swiftops stat 198 | 199 | .RS 2 200 | .PD 0 201 | .IP " Account: AUTH_43b42dae-dc0b-4a4b-ac55-97de614d6e6e" 202 | .IP "Containers: 1" 203 | .IP " Objects: 1" 204 | .IP " Bytes: 1124" 205 | .IP "Accept-Ranges: bytes" 206 | .IP "X-Trans-Id: txb21186a9eef64ed295a1e95896a0fc72" 207 | .PD 208 | .RE 209 | 210 | 211 | .SH DOCUMENTATION 212 | .LP 213 | More in depth documentation about OpenStack Swift as a whole can be found at 214 | .BI https://docs.openstack.org/swift/latest/ 215 | -------------------------------------------------------------------------------- /doc/requirements.txt: -------------------------------------------------------------------------------- 1 | keystoneauth1>=3.4.0 # Apache-2.0 2 | sphinx>=1.6.2,!=1.6.6,!=1.6.7,!=2.1.0,!=3.0.0 # BSD 3 | reno>=3.1.0 # Apache-2.0 4 | openstackdocstheme>=2.2.1 # Apache-2.0 5 | -------------------------------------------------------------------------------- /doc/source/_static/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/python-swiftclient/8486005ebd881a5c60b6ba0e802387975a5644c0/doc/source/_static/.gitignore -------------------------------------------------------------------------------- /doc/source/_templates/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/python-swiftclient/8486005ebd881a5c60b6ba0e802387975a5644c0/doc/source/_templates/.empty -------------------------------------------------------------------------------- /doc/source/client-api.rst: -------------------------------------------------------------------------------- 1 | ============================== 2 | The swiftclient.Connection API 3 | ============================== 4 | 5 | A low level API that provides methods for authentication and methods that 6 | correspond to the individual REST API calls described in the swift 7 | documentation. 8 | 9 | For usage details see the client docs: :mod:`swiftclient.client`. 10 | 11 | Authentication 12 | -------------- 13 | 14 | This section covers the various combinations of kwargs required when creating 15 | an instance of the ``Connection`` object for communicating with a swift 16 | object store. The combinations of options required for each authentication 17 | version are detailed below, but are 18 | just a subset of those that can be used to successfully authenticate. These 19 | are the most common and recommended combinations. 20 | 21 | Keystone Session 22 | ~~~~~~~~~~~~~~~~ 23 | 24 | .. code-block:: python 25 | 26 | from keystoneauth1 import session 27 | from keystoneauth1.identity import v3 28 | 29 | # Create a password auth plugin 30 | auth = v3.Password(auth_url='http://127.0.0.1:5000/v3/', 31 | username='tester', 32 | password='testing', 33 | user_domain_name='Default', 34 | project_name='Default', 35 | project_domain_name='Default') 36 | 37 | # Create session 38 | keystone_session = session.Session(auth=auth) 39 | 40 | # Create swiftclient Connection 41 | swift_conn = Connection(session=keystone_session) 42 | 43 | Keystone v3 44 | ~~~~~~~~~~~ 45 | 46 | .. code-block:: python 47 | 48 | _authurl = 'http://127.0.0.1:5000/v3/' 49 | _auth_version = '3' 50 | _user = 'tester' 51 | _key = 'testing' 52 | _os_options = { 53 | 'user_domain_name': 'Default', 54 | 'project_domain_name': 'Default', 55 | 'project_name': 'Default' 56 | } 57 | 58 | conn = Connection( 59 | authurl=_authurl, 60 | user=_user, 61 | key=_key, 62 | os_options=_os_options, 63 | auth_version=_auth_version 64 | ) 65 | 66 | Keystone v2 67 | ~~~~~~~~~~~ 68 | 69 | .. code-block:: python 70 | 71 | _authurl = 'http://127.0.0.1:5000/v2.0/' 72 | _auth_version = '2' 73 | _user = 'tester' 74 | _key = 'testing' 75 | _tenant_name = 'test' 76 | 77 | conn = Connection( 78 | authurl=_authurl, 79 | user=_user, 80 | key=_key, 81 | tenant_name=_tenant_name, 82 | auth_version=_auth_version 83 | ) 84 | 85 | Legacy Auth 86 | ~~~~~~~~~~~ 87 | 88 | .. code-block:: python 89 | 90 | _authurl = 'http://127.0.0.1:8080/' 91 | _auth_version = '1' 92 | _user = 'tester' 93 | _key = 'testing' 94 | _tenant_name = 'test' 95 | 96 | conn = Connection( 97 | authurl=_authurl, 98 | user=_user, 99 | key=_key, 100 | tenant_name=_tenant_name, 101 | auth_version=_auth_version 102 | ) 103 | 104 | Examples 105 | -------- 106 | 107 | In this section we present some simple code examples that demonstrate the usage 108 | of the ``Connection`` API. You can find full details of the options and methods 109 | available to the ``Connection`` API in the docstring generated documentation: 110 | :mod:`swiftclient.client`. 111 | 112 | List the available containers: 113 | 114 | .. code-block:: python 115 | 116 | resp_headers, containers = conn.get_account() 117 | print("Response headers: %s" % resp_headers) 118 | for container in containers: 119 | print(container) 120 | 121 | Create a new container: 122 | 123 | .. code-block:: python 124 | 125 | container = 'new-container' 126 | conn.put_container(container) 127 | resp_headers, containers = conn.get_account() 128 | if container in containers: 129 | print("The container was created") 130 | 131 | Create a new object with the contents of a local text file: 132 | 133 | .. code-block:: python 134 | 135 | container = 'new-container' 136 | with open('local.txt', 'r') as local: 137 | conn.put_object( 138 | container, 139 | 'local_object.txt', 140 | contents=local, 141 | content_type='text/plain' 142 | ) 143 | 144 | Confirm presence of the object: 145 | 146 | .. code-block:: python 147 | 148 | obj = 'local_object.txt' 149 | container = 'new-container' 150 | try: 151 | resp_headers = conn.head_object(container, obj) 152 | print('The object was successfully created') 153 | except ClientException as e: 154 | if e.http_status = '404': 155 | print('The object was not found') 156 | else: 157 | print('An error occurred checking for the existence of the object') 158 | 159 | Download the created object: 160 | 161 | .. code-block:: python 162 | 163 | obj = 'local_object.txt' 164 | container = 'new-container' 165 | resp_headers, obj_contents = conn.get_object(container, obj) 166 | with open('local_copy.txt', 'w') as local: 167 | local.write(obj_contents) 168 | 169 | Delete the created object: 170 | 171 | .. code-block:: python 172 | 173 | obj = 'local_object.txt' 174 | container = 'new-container' 175 | try: 176 | conn.delete_object(container, obj) 177 | print("Successfully deleted the object") 178 | except ClientException as e: 179 | print("Failed to delete the object with error: %s" % e) 180 | -------------------------------------------------------------------------------- /doc/source/conf.py: -------------------------------------------------------------------------------- 1 | # Swiftclient documentation build configuration file, created by 2 | # sphinx-quickstart on Tue Apr 17 02:17:37 2012. 3 | # 4 | # This file is execfile()d with the current directory set to its containing 5 | # dir. 6 | # 7 | # Note that not all possible configuration values are present in this 8 | # autogenerated file. 9 | # 10 | # All configuration values have a default; values that are commented out 11 | # serve to show the default. 12 | 13 | import sys 14 | import os 15 | 16 | 17 | # If extensions (or modules to document with autodoc) are in another directory, 18 | # add these directories to sys.path here. If the directory is relative to the 19 | # documentation root, use os.path.abspath to make it absolute, like shown here. 20 | # sys.path.append(os.path.abspath('.')) 21 | 22 | BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 23 | ROOT = os.path.abspath(os.path.join(BASE_DIR, "..", "..")) 24 | 25 | sys.path.insert(0, ROOT) 26 | 27 | 28 | # -- General configuration ---------------------------------------------------- 29 | 30 | # Add any Sphinx extension module names here, as strings. They can be 31 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. 32 | extensions = ['sphinx.ext.autodoc', 33 | 'sphinx.ext.doctest', 34 | 'sphinx.ext.todo', 35 | 'sphinx.ext.coverage', 36 | 'openstackdocstheme'] 37 | 38 | autoclass_content = 'both' 39 | autodoc_default_flags = ['members', 'undoc-members', 'show-inheritance'] 40 | 41 | # Add any paths that contain templates here, relative to this directory. 42 | templates_path = ['_templates'] 43 | 44 | # The suffix of source filenames. 45 | source_suffix = '.rst' 46 | 47 | # The encoding of source files. 48 | # source_encoding = 'utf-8' 49 | 50 | # The master toctree document. 51 | master_doc = 'index' 52 | 53 | # General information about the project. 54 | copyright = '2013-2016 OpenStack, LLC.' 55 | 56 | # -- Options for openstackdocstheme ------------------------------------------- 57 | openstackdocs_repo_name = 'openstack/python-swiftclient' 58 | openstackdocs_bug_project = 'python-swiftclient' 59 | openstackdocs_bug_tag = '' 60 | openstackdocs_pdf_link = True 61 | 62 | # The language for content autogenerated by Sphinx. Refer to documentation 63 | # for a list of supported languages. 64 | # language = None 65 | 66 | # There are two options for replacing |today|: either, you set today to some 67 | # non-false value, then it is used: 68 | # today = '' 69 | # Else, today_fmt is used as the format for a strftime call. 70 | # today_fmt = '%B %d, %Y' 71 | 72 | # List of documents that shouldn't be included in the build. 73 | # unused_docs = [] 74 | 75 | # List of directories, relative to source directory, that shouldn't be searched 76 | # for source files. 77 | exclude_trees = [] 78 | 79 | # The reST default role (used for this markup: `text`) to use for all 80 | # documents. 81 | # default_role = None 82 | 83 | # If true, '()' will be appended to :func: etc. cross-reference text. 84 | # add_function_parentheses = True 85 | 86 | # If true, the current module name will be prepended to all description 87 | # unit titles (such as .. function::). 88 | # add_module_names = True 89 | 90 | # If true, sectionauthor and moduleauthor directives will be shown in the 91 | # output. They are ignored by default. 92 | # show_authors = False 93 | 94 | # The name of the Pygments (syntax highlighting) style to use. 95 | pygments_style = 'native' 96 | 97 | # A list of ignored prefixes for module index sorting. 98 | # modindex_common_prefix = [] 99 | 100 | 101 | # -- Options for HTML output -------------------------------------------------- 102 | 103 | # The theme to use for HTML and HTML Help pages. Major themes that come with 104 | # Sphinx are currently 'default' and 'sphinxdoc'. 105 | html_theme = 'openstackdocs' 106 | 107 | # Theme options are theme-specific and customize the look and feel of a theme 108 | # further. For a list of options available for each theme, see the 109 | # documentation. 110 | # html_theme_options = {} 111 | 112 | html_theme_options = {'show_other_versions': True} 113 | 114 | # Add any paths that contain custom themes here, relative to this directory. 115 | # html_theme_path = [] 116 | 117 | # The name for this set of Sphinx documents. If None, it defaults to 118 | # " v documentation". 119 | # html_title = None 120 | 121 | # A shorter title for the navigation bar. Default is the same as html_title. 122 | # html_short_title = None 123 | 124 | # The name of an image file (relative to this directory) to place at the top 125 | # of the sidebar. 126 | # html_logo = None 127 | 128 | # The name of an image file (within the static path) to use as favicon of the 129 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 130 | # pixels large. 131 | # html_favicon = None 132 | 133 | # Add any paths that contain custom static files (such as style sheets) here, 134 | # relative to this directory. They are copied after the builtin static files, 135 | # so a file named "default.css" will overwrite the builtin "default.css". 136 | html_static_path = ['_static'] 137 | 138 | # If true, SmartyPants will be used to convert quotes and dashes to 139 | # typographically correct entities. 140 | # html_use_smartypants = True 141 | 142 | # Custom sidebar templates, maps document names to template names. 143 | # html_sidebars = {} 144 | 145 | # Additional templates that should be rendered to pages, maps page names to 146 | # template names. 147 | # html_additional_pages = {} 148 | 149 | # If false, no module index is generated. 150 | # html_use_modindex = True 151 | 152 | # If false, no index is generated. 153 | # html_use_index = True 154 | 155 | # If true, the index is split into individual pages for each letter. 156 | # html_split_index = False 157 | 158 | # If true, links to the reST sources are added to the pages. 159 | # html_show_sourcelink = True 160 | 161 | # If true, an OpenSearch description file will be output, and all pages will 162 | # contain a tag referring to it. The value of this option must be the 163 | # base URL from which the finished HTML is served. 164 | # html_use_opensearch = '' 165 | 166 | # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). 167 | # html_file_suffix = '' 168 | 169 | # Output file base name for HTML help builder. 170 | htmlhelp_basename = 'SwiftClientwebdoc' 171 | 172 | 173 | # -- Options for LaTeX output ------------------------------------------------- 174 | 175 | # The paper size ('letter' or 'a4'). 176 | # latex_paper_size = 'letter' 177 | 178 | # The font size ('10pt', '11pt' or '12pt'). 179 | # latex_font_size = '10pt' 180 | 181 | # Grouping the document tree into LaTeX files. List of tuples 182 | # (source start file, target name, title, author, documentclass [howto/manual]) 183 | latex_documents = [ 184 | ('index', 'doc-python-swiftclient.tex', 'SwiftClient Documentation', 185 | 'OpenStack, LLC.', 'manual'), 186 | ] 187 | 188 | # The name of an image file (relative to this directory) to place at the top of 189 | # the title page. 190 | # latex_logo = None 191 | 192 | # For "manual" documents, if this is true, then toplevel headings are parts, 193 | # not chapters. 194 | # latex_use_parts = False 195 | 196 | # Additional stuff for the LaTeX preamble. 197 | # latex_preamble = '' 198 | 199 | # Documents to append as an appendix to all manuals. 200 | # latex_appendices = [] 201 | 202 | # If false, no module index is generated. 203 | # latex_use_modindex = True 204 | 205 | latex_use_xindy = False 206 | -------------------------------------------------------------------------------- /doc/source/contributor/contributing.rst: -------------------------------------------------------------------------------- 1 | ============================ 2 | So You Want to Contribute... 3 | ============================ 4 | 5 | For general information on contributing to OpenStack, please check out the 6 | `contributor guide `_ to get started. 7 | It covers all the basics that are common to all OpenStack projects: the 8 | accounts you need, the basics of interacting with our Gerrit review system, how 9 | we communicate as a community, etc. 10 | 11 | The python-swiftclient is maintained by the OpenStack Swift project. 12 | To understand our development process and how you can contribute to it, please 13 | look at the Swift project's general contributor's page: 14 | http://docs.openstack.org/swift/latest/contributor/contributing.html -------------------------------------------------------------------------------- /doc/source/index.rst: -------------------------------------------------------------------------------- 1 | ====================================== 2 | Welcome to the python-swiftclient Docs 3 | ====================================== 4 | 5 | Introduction 6 | ~~~~~~~~~~~~ 7 | 8 | .. toctree:: 9 | :maxdepth: 2 10 | 11 | introduction 12 | 13 | Developer Documentation 14 | ~~~~~~~~~~~~~~~~~~~~~~~ 15 | 16 | .. toctree:: 17 | :maxdepth: 2 18 | 19 | contributor/contributing 20 | cli/index 21 | service-api 22 | client-api 23 | 24 | 25 | Code-Generated Documentation 26 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 27 | 28 | .. toctree:: 29 | :maxdepth: 2 30 | 31 | swiftclient 32 | 33 | Indices and tables 34 | ~~~~~~~~~~~~~~~~~~ 35 | 36 | * :ref:`genindex` 37 | * :ref:`modindex` 38 | * :ref:`search` 39 | 40 | License 41 | ~~~~~~~ 42 | 43 | Copyright 2013 OpenStack, LLC. 44 | 45 | Licensed under the Apache License, Version 2.0 (the "License"); 46 | you may not use this file except in compliance with the License. 47 | You may obtain a copy of the License at 48 | 49 | * http://www.apache.org/licenses/LICENSE-2.0 50 | 51 | Unless required by applicable law or agreed to in writing, software 52 | distributed under the License is distributed on an "AS IS" BASIS, 53 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 54 | See the License for the specific language governing permissions and 55 | limitations under the License. 56 | 57 | -------------------------------------------------------------------------------- /doc/source/introduction.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | Introduction 3 | ============ 4 | 5 | Where to Start? 6 | ~~~~~~~~~~~~~~~ 7 | 8 | The ``python-swiftclient`` project comprises a command line tool and two 9 | separate APIs for accessing swift programmatically. Choosing the most 10 | appropriate method for a given use case is the first problem a user needs to 11 | solve. 12 | 13 | Use Cases 14 | --------- 15 | 16 | Alongside the command line tool, the ``python-swiftclient`` includes two 17 | levels of API: 18 | 19 | * A low level client API that provides simple Python wrappers around the 20 | various authentication mechanisms and the individual HTTP requests. 21 | * A high level service API that provides methods for performing common 22 | operations in parallel on a thread pool. 23 | 24 | Example use cases: 25 | 26 | * Uploading and retrieving data 27 | Use the command line tool if you are simply uploading and downloading 28 | files and directories to and from your filesystem. The command line tool 29 | can be integrated into a shell script to automate tasks. 30 | 31 | * Integrating into an automated Python workflow 32 | Use the ``SwiftService`` API to perform operations offered by the CLI 33 | if your use case requires integration with a Python-based workflow. 34 | This method offers greater control and flexibility over individual object 35 | operations, such as the metadata set on each object. The ``SwiftService`` 36 | class provides methods to perform multiple sets of operations against a 37 | swift object store using a configurable shared thread pool. A single 38 | instance of the ``SwiftService`` class can be shared between multiple 39 | threads in your own code. 40 | 41 | * Developing an application in Python to access a swift object store 42 | Use the ``SwiftService`` API to develop Python applications that use 43 | swift to store and retrieve objects. A ``SwiftService`` instance provides 44 | a configurable thread pool for performing all operations supported by the 45 | CLI. 46 | 47 | * Fine-grained control over threading or the requests being performed 48 | Use the ``Connection`` API if your use case requires fine grained control 49 | over advanced features or you wish to use your own existing threading 50 | model. Examples of advanced features requiring the use of the 51 | ``Connection`` API include creating an SLO manifest that references 52 | already existing objects, or fine grained control over the query strings 53 | supplied with each HTTP request. 54 | 55 | Important considerations 56 | ~~~~~~~~~~~~~~~~~~~~~~~~ 57 | 58 | This section covers some important considerations, helpful hints, and things to 59 | avoid when integrating an object store into your workflow. 60 | 61 | An object store is not a filesystem 62 | ----------------------------------- 63 | 64 | It cannot be stressed enough that your usage of the object store should reflect 65 | the proper use case, and not treat the storage like a traditional filesystem. 66 | There are two main restrictions to bear in mind when designing an application 67 | that uses an object store: 68 | 69 | * You cannot rename objects. Due to fact that the name of an object is one 70 | of the factors that determines where the object and its replicas are stored, 71 | renaming would require multiple copies of the data to be moved between 72 | physical storage devices. If you want to rename an object you must upload 73 | to the new location, or make a server side copy request to the new location, 74 | and then delete the original. 75 | 76 | * You cannot modify objects. Objects are stored in multiple locations and 77 | are checked for integrity based on the MD5 sum calculated during 78 | upload. In order to modify the contents of an object, the entire desired 79 | contents must be re-uploaded. In certain special cases it is possible to 80 | work around this restriction using large objects, but no general 81 | file-like access is available to modify a stored object. 82 | 83 | Objects cannot be locked 84 | ------------------------ 85 | 86 | There is no mechanism to perform a combination of reading the 87 | data/metadata from an object and writing an update to that data/metadata in an 88 | atomic way. Any user with access to a container could update the contents or 89 | metadata associated with an object at any time. 90 | 91 | Workflows that assume that no updates have been made since the last read of an 92 | object should be discouraged. Enabling a workflow of this type requires an 93 | external object locking mechanism and/or cooperation between all clients 94 | accessing the data. 95 | -------------------------------------------------------------------------------- /doc/source/swiftclient.rst: -------------------------------------------------------------------------------- 1 | .. _swiftclient_package: 2 | 3 | swiftclient 4 | ============== 5 | 6 | .. automodule:: swiftclient 7 | :inherited-members: 8 | 9 | swiftclient.authv1 10 | ================== 11 | 12 | .. automodule:: swiftclient.authv1 13 | :inherited-members: 14 | 15 | swiftclient.client 16 | ================== 17 | 18 | .. automodule:: swiftclient.client 19 | :inherited-members: 20 | 21 | swiftclient.service 22 | =================== 23 | 24 | .. automodule:: swiftclient.service 25 | :inherited-members: 26 | 27 | swiftclient.exceptions 28 | ====================== 29 | 30 | .. automodule:: swiftclient.exceptions 31 | :inherited-members: 32 | 33 | swiftclient.multithreading 34 | ========================== 35 | 36 | .. automodule:: swiftclient.multithreading 37 | 38 | swiftclient.utils 39 | ================= 40 | 41 | .. automodule:: swiftclient.utils 42 | :inherited-members: 43 | -------------------------------------------------------------------------------- /examples/capabilities.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from swiftclient.exceptions import ClientException 4 | from swiftclient.service import SwiftService 5 | 6 | logging.basicConfig(level=logging.ERROR) 7 | logging.getLogger("requests").setLevel(logging.CRITICAL) 8 | logging.getLogger("swiftclient").setLevel(logging.CRITICAL) 9 | logger = logging.getLogger(__name__) 10 | 11 | with SwiftService() as swift: 12 | try: 13 | capabilities_result = swift.capabilities() 14 | capabilities = capabilities_result['capabilities'] 15 | if 'slo' in capabilities: 16 | print('SLO is supported') 17 | else: 18 | print('SLO is not supported') 19 | except ClientException as e: 20 | logger.error(e.value) 21 | -------------------------------------------------------------------------------- /examples/copy.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from swiftclient.service import SwiftService, SwiftCopyObject, SwiftError 4 | 5 | logging.basicConfig(level=logging.ERROR) 6 | logging.getLogger("requests").setLevel(logging.CRITICAL) 7 | logging.getLogger("swiftclient").setLevel(logging.CRITICAL) 8 | logger = logging.getLogger(__name__) 9 | 10 | with SwiftService() as swift: 11 | try: 12 | obj = SwiftCopyObject("c", {"destination": "/cont/d"}) 13 | for i in swift.copy( 14 | "cont", ["a", "b", obj], 15 | {"meta": ["foo:bar"], "destination": "/cc"}): 16 | if i["success"]: 17 | if i["action"] == "copy_object": 18 | print( 19 | "object %s copied from /%s/%s" % 20 | (i["destination"], i["container"], i["object"]) 21 | ) 22 | elif i["action"] == "create_container": 23 | print( 24 | "container %s created" % i["container"] 25 | ) 26 | else: 27 | if "error" in i and isinstance(i["error"], Exception): 28 | raise i["error"] 29 | except SwiftError as e: 30 | logger.error(e.value) 31 | -------------------------------------------------------------------------------- /examples/delete.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from swiftclient.service import SwiftService 4 | from sys import argv 5 | 6 | 7 | logging.basicConfig(level=logging.ERROR) 8 | logging.getLogger("requests").setLevel(logging.CRITICAL) 9 | logging.getLogger("swiftclient").setLevel(logging.CRITICAL) 10 | logger = logging.getLogger(__name__) 11 | 12 | _opts = {'object_dd_threads': 20} 13 | container = argv[1] 14 | objects = argv[2:] 15 | with SwiftService(options=_opts) as swift: 16 | del_iter = swift.delete(container=container, objects=objects) 17 | for del_res in del_iter: 18 | c = del_res.get('container', '') 19 | o = del_res.get('object', '') 20 | a = del_res.get('attempts') 21 | if del_res['success'] and not del_res['action'] == 'bulk_delete': 22 | rd = del_res.get('response_dict') 23 | if rd is not None: 24 | t = dict(rd.get('headers', {})) 25 | if t: 26 | print( 27 | 'Successfully deleted {0}/{1} in {2} attempts ' 28 | '(transaction id: {3})'.format(c, o, a, t) 29 | ) 30 | else: 31 | print( 32 | 'Successfully deleted {0}/{1} in {2} ' 33 | 'attempts'.format(c, o, a) 34 | ) 35 | -------------------------------------------------------------------------------- /examples/download.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from swiftclient.service import SwiftService, SwiftError 4 | from sys import argv 5 | 6 | logging.basicConfig(level=logging.ERROR) 7 | logging.getLogger("requests").setLevel(logging.CRITICAL) 8 | logging.getLogger("swiftclient").setLevel(logging.CRITICAL) 9 | logger = logging.getLogger(__name__) 10 | 11 | def is_png(obj): 12 | return ( 13 | obj["name"].lower().endswith('.png') or 14 | obj["content_type"] == 'image/png' 15 | ) 16 | 17 | container = argv[1] 18 | with SwiftService() as swift: 19 | try: 20 | list_options = {"prefix": "archive_2016-01-01/"} 21 | list_parts_gen = swift.list(container=container) 22 | for page in list_parts_gen: 23 | if page["success"]: 24 | objects = [ 25 | obj["name"] for obj in page["listing"] if is_png(obj) 26 | ] 27 | for down_res in swift.download( 28 | container=container, 29 | objects=objects): 30 | if down_res['success']: 31 | print("'%s' downloaded" % down_res['object']) 32 | else: 33 | print("'%s' download failed" % down_res['object']) 34 | else: 35 | raise page["error"] 36 | except SwiftError as e: 37 | logger.error(e.value) 38 | -------------------------------------------------------------------------------- /examples/list.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from swiftclient.service import SwiftService, SwiftError 4 | from sys import argv 5 | 6 | logging.basicConfig(level=logging.ERROR) 7 | logging.getLogger("requests").setLevel(logging.CRITICAL) 8 | logging.getLogger("swiftclient").setLevel(logging.CRITICAL) 9 | logger = logging.getLogger(__name__) 10 | 11 | container = argv[1] 12 | minimum_size = 10*1024**2 13 | with SwiftService() as swift: 14 | try: 15 | list_parts_gen = swift.list(container=container) 16 | for page in list_parts_gen: 17 | if page["success"]: 18 | for item in page["listing"]: 19 | 20 | i_size = int(item["bytes"]) 21 | if i_size > minimum_size: 22 | i_name = item["name"] 23 | i_etag = item["hash"] 24 | print( 25 | "%s [size: %s] [etag: %s]" % 26 | (i_name, i_size, i_etag) 27 | ) 28 | else: 29 | raise page["error"] 30 | 31 | except SwiftError as e: 32 | logger.error(e.value) 33 | -------------------------------------------------------------------------------- /examples/post.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from swiftclient.service import SwiftService, SwiftError 4 | from sys import argv 5 | 6 | logging.basicConfig(level=logging.ERROR) 7 | logging.getLogger("requests").setLevel(logging.CRITICAL) 8 | logging.getLogger("swiftclient").setLevel(logging.CRITICAL) 9 | logger = logging.getLogger(__name__) 10 | 11 | container = argv[1] 12 | with SwiftService() as swift: 13 | try: 14 | list_options = {"prefix": "archive_2016-01-01/"} 15 | list_parts_gen = swift.list(container=container) 16 | for page in list_parts_gen: 17 | if page["success"]: 18 | objects = [obj["name"] for obj in page["listing"]] 19 | post_options = {"header": "X-Delete-After:86400"} 20 | for post_res in swift.post( 21 | container=container, 22 | objects=objects, 23 | options=post_options): 24 | if post_res['success']: 25 | print("Object '%s' POST success" % post_res['object']) 26 | else: 27 | print("Object '%s' POST failed" % post_res['object']) 28 | else: 29 | raise page["error"] 30 | except SwiftError as e: 31 | logger.error(e.value) 32 | -------------------------------------------------------------------------------- /examples/stat.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import pprint 3 | 4 | from swiftclient.service import SwiftService 5 | from sys import argv 6 | 7 | logging.basicConfig(level=logging.ERROR) 8 | logging.getLogger("requests").setLevel(logging.CRITICAL) 9 | logging.getLogger("swiftclient").setLevel(logging.CRITICAL) 10 | logger = logging.getLogger(__name__) 11 | 12 | _opts = {'object_dd_threads': 20} 13 | with SwiftService(options=_opts) as swift: 14 | container = argv[1] 15 | objects = argv[2:] 16 | header_data = {} 17 | stats_it = swift.stat(container=container, objects=objects) 18 | for stat_res in stats_it: 19 | if stat_res['success']: 20 | header_data[stat_res['object']] = stat_res['headers'] 21 | else: 22 | logger.error( 23 | 'Failed to retrieve stats for %s' % stat_res['object'] 24 | ) 25 | pprint.pprint(header_data) 26 | -------------------------------------------------------------------------------- /examples/upload.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from os import walk 4 | from os.path import join 5 | from swiftclient.multithreading import OutputManager 6 | from swiftclient.service import SwiftError, SwiftService, SwiftUploadObject 7 | from sys import argv 8 | 9 | logging.basicConfig(level=logging.ERROR) 10 | logging.getLogger("requests").setLevel(logging.CRITICAL) 11 | logging.getLogger("swiftclient").setLevel(logging.CRITICAL) 12 | logger = logging.getLogger(__name__) 13 | 14 | _opts = {'object_uu_threads': 20} 15 | dir = argv[1] 16 | container = argv[2] 17 | with SwiftService(options=_opts) as swift, OutputManager() as out_manager: 18 | try: 19 | # Collect all the files and folders in the given directory 20 | objs = [] 21 | dir_markers = [] 22 | for (_dir, _ds, _fs) in walk(dir): 23 | if not (_ds + _fs): 24 | dir_markers.append(_dir) 25 | else: 26 | objs.extend([join(_dir, _f) for _f in _fs]) 27 | 28 | # Now that we've collected all the required files and dir markers 29 | # build the ``SwiftUploadObject``s for the call to upload 30 | objs = [ 31 | SwiftUploadObject( 32 | o, object_name=o.replace( 33 | dir, 'my-%s-objects' % dir, 1 34 | ) 35 | ) for o in objs 36 | ] 37 | dir_markers = [ 38 | SwiftUploadObject( 39 | None, object_name=d.replace( 40 | dir, 'my-%s-objects' % dir, 1 41 | ), options={'dir_marker': True} 42 | ) for d in dir_markers 43 | ] 44 | 45 | # Schedule uploads on the SwiftService thread pool and iterate 46 | # over the results 47 | for r in swift.upload(container, objs + dir_markers): 48 | if r['success']: 49 | if 'object' in r: 50 | print(r['object']) 51 | elif 'for_object' in r: 52 | print( 53 | '%s segment %s' % (r['for_object'], 54 | r['segment_index']) 55 | ) 56 | else: 57 | error = r['error'] 58 | if r['action'] == "create_container": 59 | logger.warning( 60 | 'Warning: failed to create container ' 61 | "'%s'%s", container, error 62 | ) 63 | elif r['action'] == "upload_object": 64 | logger.error( 65 | "Failed to upload object %s to container %s: %s" % 66 | (container, r['object'], error) 67 | ) 68 | else: 69 | logger.error("%s" % error) 70 | 71 | except SwiftError as e: 72 | logger.error(e.value) 73 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools", "pbr"] 3 | build-backend = "setuptools.build_meta" 4 | -------------------------------------------------------------------------------- /releasenotes/notes/310-notes-03040158a8683dd8.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - Added a copy object method. 4 | - Arbitrary query strings can now be passed into container functions. 5 | - > 6 | Client certificate and key can now be specified via CLI 7 | options (--os-cert/--os-key) or environment variables ($OS_CERT/$OS_KEY). 8 | - > 9 | A new CLI option `--ignore-checksum` can be specified to turn off 10 | checksum validation. In the SDK, the new `checksum=True` parameter can 11 | be used for the same purpose. 12 | - Added --json option to `swift capabilities` / `swift info` 13 | - Default to v3 auth if we find a (user|project)-domain-(name|id) option. 14 | - Added a Python version constraint of >= Py27. 15 | - > 16 | `client.py` will now retry on a 401 (auth error) even if `retries` is 17 | set to zero. 18 | - Fixed `swift download` when `marker` was specified. 19 | - Object segments uploaded via swiftclient are now given the content type 20 | "application/swiftclient-segment". 21 | - > 22 | "Directory marker" objects are now given a "application/directory" 23 | content type to match both Swift's `staticweb` feature and other 24 | ecosystem tools. 25 | - > 26 | Strip leading/trailing whitespace from headers (otherwise, new versions 27 | of the requests library will raise an InvalidHeader error). Additionally, 28 | header values with standard types (integer, float, or bool) are coerced 29 | to strings before being sent to a socket. 30 | - > 31 | Non-python dependencies are now specified in bindep.txt. Currently this 32 | only lists a single dependency for testing (PyPy), but if future 33 | dependencies are added, they will be included in this file. 34 | - Client exceptions now include response headers. One benefit is that 35 | this allows clients to see transaction IDs without needing to turn on 36 | debug logging. 37 | - Client connections now accept gzip-encoded responses. 38 | - Various other minor bug fixes and improvements. 39 | -------------------------------------------------------------------------------- /releasenotes/notes/320_notes-bb367dba1053d34c.yaml: -------------------------------------------------------------------------------- 1 | features: 2 | - > 3 | Added Keystone session support and a "v1password" plugin for Keystone. 4 | This plugin provides a way for Keystone sessions (and clients that 5 | use them, like python-openstackclient) to communicate with old auth 6 | endpoints that still use this mechanism. 7 | 8 | - > 9 | HEAD, GET, and DELETE now support sending additional headers to match 10 | existing functionality on PUT requests. 11 | 12 | - Various other minor bug fixes and improvements. 13 | -------------------------------------------------------------------------------- /releasenotes/notes/340_notes-1777780bbfdb4d96.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | 4 | - The ``swift`` CLI now supports streaming from stdin. If "-" is given 5 | as the source, the object content is read from stdin. The 6 | ``--object-name`` must be given when content is loaded from stdin. 7 | - Tolerate RFC-compliant ETags returned from the server. 8 | - Skip checksum validation on partial downloads. 9 | - Buffer reads from disk, resulting in much faster upload throughput. 10 | - > 11 | Added support for ISO 8601 timestamps for tempurl, matching the 12 | feature in Swift 2.13.0. 13 | - Added an option to ignore mtime metadata entry (``--ignore-mtime``). 14 | - > 15 | When using SwiftService to delete many objects, the bulk delete page 16 | size will now be respected. Previously, exceeding this limit would 17 | prevent any objects from being deleted. 18 | - Expose `--prefix` as an option for st_delete. 19 | - Imported docs content from openstack-manuals project. 20 | - Various other minor bug fixes and improvements. 21 | -------------------------------------------------------------------------------- /releasenotes/notes/350_notes-ad0ae19704b2eb88.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Allow for object uploads > 5GB from stdin. 5 | 6 | When uploading from standard input, swiftclient will turn the upload 7 | into an SLO in the case of large objects. By default, input larger 8 | than 10MB will be uploaded as an SLO with 10MB segment sizes. Users 9 | can also supply the ``--segment-size`` option to alter that 10 | threshold and the SLO segment size. One segment is buffered in 11 | memory (which is why 10MB default was chosen). 12 | 13 | - | 14 | The ``--meta`` option can now be set on the upload command. 15 | 16 | - | 17 | Updated PyPy test dependency references to be more accurate 18 | on different distros. 19 | -------------------------------------------------------------------------------- /releasenotes/notes/360_notes-1ec385df13a3a735.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Add the ``--prompt`` option for the CLI which will cause the user to be 5 | prompted to enter a password. Any password otherwise specified by 6 | ``--key`` , ``--os-password`` or an environment variable will be ignored. 7 | 8 | - | 9 | Added bash completion support to the ``swift`` CLI. Enable this by sourcing 10 | the included ``tools/swift.bash_completion`` file. Make it permanent by 11 | including this file in the system's ``/etc/bash_completion.d`` directory. 12 | 13 | - | 14 | Add ability to generate a temporary URL with an IP range restriction. 15 | TempURLs with IP restrictions are supported are Swift 2.19.0 or later. 16 | 17 | - | 18 | The client.py SDK now supports a ``query_string`` option on the 19 | ``head_object()`` method. This is useful for finding information on 20 | SLO/DLO manifests without fetching the entire manifest. 21 | 22 | - | 23 | The client.py SDK now respects ``region_name`` when using sessions. 24 | 25 | - | 26 | Added a ``.close()`` method to an object response, allowing clients to give 27 | up on reading the rest of the response body, if they so choose. 28 | 29 | - | 30 | Fixed a bug where using ``--debug`` in the CLI with unicode account names 31 | would cause a client crash. 32 | 33 | - | 34 | Make OS_AUTH_URL work in DevStack (for testing) by default. 35 | 36 | - | 37 | Dropped Python 3.4 testing. 38 | 39 | - | 40 | Various other minor bug fixes and improvements. 41 | -------------------------------------------------------------------------------- /releasenotes/notes/361_notes-59e020e68bcdd709.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - | 4 | Added the delimiter keyword parameter to ``get_account()`` to match the 5 | functionality of ``get_container()``. 6 | 7 | - | 8 | Fixed an issue in the client module where socket connections weren't 9 | closed properly before being dereferenced. 10 | 11 | - | 12 | Various other minor bug fixes and improvements. 13 | -------------------------------------------------------------------------------- /releasenotes/notes/3_8_0_release-bd867fbdb8c895d3.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Added a new ``--json`` option to ``swift list``. 5 | fixes: 6 | - | 7 | Fixed an issue introduced in 3.5.0 where re-uploading an SLO with 8 | the same size, mtime, and segment size would delete all of the 9 | just-uploaded segments. 10 | -------------------------------------------------------------------------------- /releasenotes/notes/3_8_1_release-cb5648c3ae69bde1.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fixes: 3 | - | 4 | Deleting or overwriting a symlink to an SLO or DLO will no longer attempt 5 | to clean up the large object's segments. 6 | - | 7 | Fixed an issue sending non-ASCII metadata keys on Python 3. 8 | Note that *receiving* such metadata on py3 is `still broken 9 | `__. 10 | other: 11 | - | 12 | Documentation can now be rendered as a PDF. 13 | - | 14 | Dropped Python 3.5 testing. 15 | -------------------------------------------------------------------------------- /releasenotes/notes/3_9_0_release-3c293d277f14ec22.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Now tested under Python 3.8. 5 | 6 | fixes: 7 | - | 8 | Better clean up connections when using the low-level ``client.py`` API. 9 | 10 | - | 11 | Fixed a display issue when ``swift delete`` made multiple attempts to 12 | bulk delete objects. 13 | -------------------------------------------------------------------------------- /releasenotes/notes/4_3_0_release.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | features: 3 | - | 4 | Static Large Objects will now be used by default for segmented uploads 5 | to clusters that support them. The new ``--use-dlo`` option may be used to 6 | create Dynamic Large Objects, as was the previous behavior without 7 | ``--use-slo``. 8 | 9 | - | 10 | Uploads from stdin may now be Dynamic Large Objects by using the new 11 | ``--use-dlo`` option. 12 | 13 | - | 14 | The ``--timeout`` option may now include 's', 'm', and 'h' suffixes similar 15 | to the ``tempurl`` ``