{"id":15562136,"url":"https://github.com/mrkamel/swift_client","last_synced_at":"2025-07-28T17:08:33.677Z","repository":{"id":24815214,"uuid":"28229531","full_name":"mrkamel/swift_client","owner":"mrkamel","description":"Small but powerful client to interact with OpenStack Swift","archived":false,"fork":false,"pushed_at":"2021-01-18T19:15:43.000Z","size":70,"stargazers_count":15,"open_issues_count":1,"forks_count":12,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-27T07:44:20.915Z","etag":null,"topics":["client","gem","library","openstack-swift","ruby"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mrkamel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-12-19T12:59:55.000Z","updated_at":"2021-05-10T00:26:12.000Z","dependencies_parsed_at":"2022-06-30T00:32:47.948Z","dependency_job_id":null,"html_url":"https://github.com/mrkamel/swift_client","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/mrkamel/swift_client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrkamel%2Fswift_client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrkamel%2Fswift_client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrkamel%2Fswift_client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrkamel%2Fswift_client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrkamel","download_url":"https://codeload.github.com/mrkamel/swift_client/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrkamel%2Fswift_client/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267552097,"owners_count":24106000,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-28T02:00:09.689Z","response_time":68,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["client","gem","library","openstack-swift","ruby"],"created_at":"2024-10-02T16:11:55.733Z","updated_at":"2025-07-28T17:08:33.623Z","avatar_url":"https://github.com/mrkamel.png","language":"Ruby","readme":"[![Build Status](https://secure.travis-ci.org/mrkamel/swift_client.png?branch=master)](http://travis-ci.org/mrkamel/swift_client)\n[![Code Climate](https://codeclimate.com/github/mrkamel/swift_client.png)](https://codeclimate.com/github/mrkamel/swift_client)\n[![Dependency Status](https://gemnasium.com/mrkamel/swift_client.png?travis)](https://gemnasium.com/mrkamel/swift_client)\n[![Gem Version](https://badge.fury.io/rb/swift_client.svg)](http://badge.fury.io/rb/swift_client)\n\n# SwiftClient\n\nSmall but powerful client to interact with OpenStack Swift.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'swift_client'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install swift_client\n\n## Usage\n\nFirst, connect to a Swift cluster:\n\n```ruby\nswift_client = SwiftClient.new(\n  :auth_url =\u003e \"https://example.com/auth/v1.0\",\n  :username =\u003e \"account:username\",\n  :api_key =\u003e \"api key\",\n  :temp_url_key =\u003e \"temp url key\",\n  :storage_url =\u003e \"https://example.com/v1/AUTH_account\"\n)\n```\n\nTo connect via v2 you have to add version and method specific details:\n\n```ruby\nswift_client = SwiftClient.new(\n  :auth_url =\u003e \"https://auth.example.com/v2.0\",\n  :storage_url =\u003e \"https://storage.example.com/v1/AUTH_account\",\n  :tenant_name =\u003e \"tenant\",\n  :username =\u003e \"username\",\n  :password =\u003e \"password\"\n)\n\n# OR\n\nswift_client = SwiftClient.new(\n  :auth_url =\u003e \"https://auth.example.com/v2.0\",\n  :storage_url =\u003e \"https://storage.example.com/v1/AUTH_account\",\n  :tenant_name =\u003e \"tenant\",\n  :access_key =\u003e \"access key\",\n  :secret_key =\u003e \"secret key\"\n)\n```\n\nTo connect via v3:\n\n```ruby\nswift_client = SwiftClient.new(\n  :auth_url =\u003e \"https://auth.example.com/v3\",\n  :storage_url =\u003e \"https://storage.example.com/v1/AUTH_account\",\n  :username =\u003e \"username\",\n  :password =\u003e \"password\",\n  :user_domain =\u003e \"example.com\" # :user_domain_id =\u003e \"...\" is valid as well\n)\n\n# OR\n\n# project scoped authentication\n\nswift_client = SwiftClient.new(\n  :auth_url =\u003e \"https://auth.example.com/v3\",\n  :username =\u003e \"username\",\n  :password =\u003e \"password\",\n  :user_domain =\u003e \"example.com\", # :user_domain_id =\u003e \"...\" is valid as well\n  :project_id =\u003e \"p-123456\", # :project_name =\u003e \"...\" is valid as well\n  :project_domain_id =\u003e \"d-123456\" # :project_domain_name =\u003e \"...\" is valid as well\n)\n\n# OR\n\n# domain scoped authentication\n\nswift_client = SwiftClient.new(\n  :auth_url =\u003e \"https://auth.example.com/v3\",\n  :username =\u003e \"username\",\n  :password =\u003e \"password\",\n  :user_domain =\u003e \"example.com\", # :user_domain_id =\u003e \"...\" is valid as well\n  :domain_id =\u003e \"d-123456\" # :domain_name =\u003e \"...\" is valid as well\n)\n\n# OR\n\nswift_client = SwiftClient.new(\n  :auth_url =\u003e \"https://auth.example.com/v3\",\n  :storage_url =\u003e \"https://storage.example.com/v1/AUTH_account\",\n  :user_id =\u003e \"user id\",\n  :password =\u003e \"password\",\n  :interface =\u003e \"internal\"\n)\n\n# OR\n\nswift_client = SwiftClient.new(\n  :auth_url =\u003e \"https://auth.example.com/v3\",\n  :storage_url =\u003e \"https://storage.example.com/v1/AUTH_account\",\n  :token =\u003e \"token\"\n)\n```\n\nwhere `temp_url_key` and `storage_url` are optional.\n\nSwiftClient will automatically reconnect in case the endpoint responds with 401\nUnauthorized to one of your requests using the provided credentials. In case\nthe endpoint does not respond with 2xx to any of SwiftClient's requests,\nSwiftClient will raise a `SwiftClient::ResponseError`. Otherwise, SwiftClient\nresponds with an `HTTParty::Response` object, such that you can call `#headers`\nto access the response headers or `#body` as well as `#parsed_response` to\naccess the response body and JSON response. Checkout the\n[HTTParty](https://github.com/jnunemaker/httparty) gem to learn more.\n\nSwiftClient offers the following requests:\n\n* `head_account(options = {}) # =\u003e HTTParty::Response`\n* `post_account(headers = {}, options = {}) # =\u003e HTTParty::Response`\n* `head_containers(options = {}) # =\u003e HTTParty::Response`\n* `get_containers(query = nil, options = {}) # =\u003e HTTParty::Response`\n* `paginate_containers(query = nil, options = {}) # =\u003e Enumerator`\n* `get_container(container_name, query = nil, options = {}) # =\u003e HTTParty::Response`\n* `paginate_container(container_name, query = nil, options = {}) # =\u003e Enumerator`\n* `head_container(container_name, options = {}) # =\u003e HTTParty::Response`\n* `put_container(container_name, headers = {}, options = {}) # =\u003e HTTParty::Response`\n* `post_container(container_name, headers = {}, options = {}) # =\u003e HTTParty::Response`\n* `delete_container(container_name, options = {}) # =\u003e HTTParty::Response`\n* `put_object(object_name, data_or_io, container_name, headers = {}, options = {}) # =\u003e HTTParty::Response`\n* `post_object(object_name, container_name, headers = {}, options = {}) # =\u003e HTTParty::Response`\n* `get_object(object_name, container_name, options = {}) -\u003e HTTParty::Response`\n* `get_object(object_name, container_name, options = {}) { |chunk| save chunk } # =\u003e HTTParty::Response`\n* `head_object(object_name, container_name, options = {}) # =\u003e HTTParty::Response`\n* `delete_object(object_name, container_name, options = {}) # =\u003e HTTParty::Response`\n* `get_objects(container_name, query = nil, options = {}) # =\u003e HTTParty::Response`\n* `paginate_objects(container_name, query = nil, options = {}) # =\u003e Enumerator`\n* `public_url(object_name, container_name) # =\u003e HTTParty::Response`\n* `temp_url(object_name, container_name, options = {}) # =\u003e HTTParty::Response`\n* `bulk_delete(entries, options = {}) # =\u003e entries`\n* `post_head(object_name, container_name, _headers = {}, options = {}) # =\u003e HTTParty::Response`\n\nBy default, the client instructs the Swift server to return JSON via an HTTP Accept header; to disable this pass `:json =\u003e false` in `options`. The rest of the `options` are passed directly to the internal [HTTParty](https://rubygems.org/gems/httparty) client.\n\n### Getting large objects\n\nThe `get_object` method with out a block is suitable for small objects that easily fit in memory. For larger objects, specify a block to process chunked data as it comes in.\n\n```ruby\nFile.open(\"/tmp/output\", \"wb\") do |file_io|\n  swift_client.get_object(\"/large/object\", \"container\") do |chunk|\n    file_io.write(chunk)\n  end\nend\n```\n\n## Re-Using/Sharing/Caching Auth Tokens\n\nCertain OpenStack/Swift providers have limits in place regarding token\ngeneration. To re-use auth tokens by caching them via memcached, install dalli\n\n`gem install dalli`\n\nand provide an instance of Dalli::Client to SwiftClient:\n\n```ruby\nswift_client = SwiftClient.new(\n  :auth_url =\u003e \"https://example.com/auth/v1.0\",\n  ...\n  :cache_store =\u003e Dalli::Client.new\n)\n```\n\nThe cache key used to store the auth token will include all neccessary details\nto ensure the auth token won't be used for a different swift account erroneously.\n\nThe cache implementation of SwiftClient is not restricted to memcached. To use\na different one, simply implement a driver for your favorite cache store. See\n[null_cache.rb](https://github.com/mrkamel/swift_client/blob/master/lib/swift_client/null_cache.rb)\nfor more info.\n\n## bulk_delete\n\nTakes an array containing container_name/object_name entries.\nAutomatically slices and sends 1_000 items per request.\n\n## Non-chunked uploads\n\nBy default files are uploaded in chunks and using a `Transfer-Encoding:\nchunked` header. You can override this by passing a `Transfer-Encoding:\nidentity` header:\n\n```ruby\nput_object(object_name, data_or_io, container_name, \"Transfer-Encoding\" =\u003e \"identity\")\n```\n\n## Contributing\n\n1. Fork it ( https://github.com/mrkamel/swift_client/fork )\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\n## Semantic Versioning\n\nStarting with version 0.2.0, SwiftClient uses Semantic Versioning:\n[SemVer](http://semver.org/)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrkamel%2Fswift_client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrkamel%2Fswift_client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrkamel%2Fswift_client/lists"}