{"id":13502056,"url":"https://github.com/mardix/flask-cloudy","last_synced_at":"2025-04-05T10:08:44.256Z","repository":{"id":32415065,"uuid":"35992047","full_name":"mardix/flask-cloudy","owner":"mardix","description":"A Flask extension to access, upload, download, save and delete files on cloud storage providers such as: AWS S3, Google Storage, Microsoft Azure, Rackspace Cloudfiles, and even Local file system","archived":false,"fork":false,"pushed_at":"2019-11-12T02:53:30.000Z","size":53,"stargazers_count":244,"open_issues_count":12,"forks_count":55,"subscribers_count":16,"default_branch":"master","last_synced_at":"2024-04-26T14:31:32.741Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"SocialiteProviders/VKontakte","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mardix.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-05-21T05:04:50.000Z","updated_at":"2024-03-06T02:22:49.000Z","dependencies_parsed_at":"2022-08-26T02:42:44.034Z","dependency_job_id":null,"html_url":"https://github.com/mardix/flask-cloudy","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mardix%2Fflask-cloudy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mardix%2Fflask-cloudy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mardix%2Fflask-cloudy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mardix%2Fflask-cloudy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mardix","download_url":"https://codeload.github.com/mardix/flask-cloudy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247318744,"owners_count":20919484,"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","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":[],"created_at":"2024-07-31T22:02:00.098Z","updated_at":"2025-04-05T10:08:44.228Z","avatar_url":"https://github.com/mardix.png","language":"Python","funding_links":[],"categories":["Python","Open Source Repos"],"sub_categories":["S3"],"readme":"# Flask-Cloudy\n\n\n## About\n\nA Flask extension to **access, upload, download, save and delete** files on cloud storage providers such as: \nAWS S3, Google Storage, Microsoft Azure, Rackspace Cloudfiles, and even Local file system.\n\nFor local file storage, it also provides a flask endpoint to access the files.\n \n \nVersion: 1.x.x\n\n---\n\n## TLDR: Quick Example\n```py\n\tfrom flask import Flask, request\n\tfrom flask_cloudy import Storage\n\t\n\tapp = Flask(__name__)\n\t\n\t# Update the config \n\tapp.config.update({\n\t\t\"STORAGE_PROVIDER\": \"LOCAL\", # Can also be S3, GOOGLE_STORAGE, etc... \n\t\t\"STORAGE_KEY\": \"\",\n\t\t\"STORAGE_SECRET\": \"\",\n\t\t\"STORAGE_CONTAINER\": \"./\",  # a directory path for local, bucket name of cloud\n\t\t\"STORAGE_SERVER\": True,\n\t\t\"STORAGE_SERVER_URL\": \"/files\" # The url endpoint to access files on LOCAL provider\n\t})\n\t\n\t# Setup storage\n\tstorage = Storage()\n\tstorage.init_app(app) \n\t\n    @app.route(\"/upload\", methods=[\"POST\", \"GET\"])\n    def upload():\n        if request.method == \"POST\":\n        \tfile = request.files.get(\"file\")\n            my_upload = storage.upload(file)\n            \n            # some useful properties\n            name = my_upload.name\n            extension = my_upload.extension\n            size = my_upload.size\n            url = my_upload.url\n            \n            return url\n        \n    # Pretending the file uploaded is \"my-picture.jpg\"    \n\t# it will return a url in the format: http://domain.com/files/my-picture.jpg\n\n\n\t# A download endpoint, to download the file\n    @app.route(\"/download/\u003cpath:object_name\u003e\")\n    def download(object_name):\n        my_object = storage.get(object_name)\n        if my_object:\n        \tdownload_url = my_object.download()\n        \treturn download_url\n        else:\t\n        \tabort(404, \"File doesn't exist\")\n```\n---        \n       \nGo to the \"example\" directory to get a workable flask-cloud example\n\n\n--- \n  \n  \n### Features:\n\n- Browse files\n\n- Upload files\n\n- Download files\n\n- Delete files\n\n- Serve files via http\n\n\n### Supported storage:\n\n- AWS S3\n\n- Google Storage\n\n- Microsoft Azure\n\n- Rackspace CloudFiles\n\n- Local (for local file system)\n\n\n**Dependecies:** (They will be installed upon setup)\n\n- Flask\n\n- Apache-Libcloud \n \n---\n\n## Install \u0026 Config\n\n    pip install flask-cloudy\n\n---\n\n(To use it as standalone, refer to API documentaion below)\n\n## Config for Flask\n\nWithin your Flask application's settings you can provide the following settings to control\nthe behavior of Flask-Cloudy\n \n\n**- STORAGE_PROVIDER** (str) \n\n- LOCAL\n- S3\n- S3_US_WEST\n- S3_US_WEST_OREGON\n- S3_EU_WEST\n- S3_AP_SOUTHEAST\n- S3_AP_NORTHEAST\n- GOOGLE_STORAGE\n- AZURE_BLOBS\n- CLOUDFILES\n\n\n**- STORAGE_KEY** (str)\n\nThe access key of the cloud storage provider\n\nNone for LOCAL\n\n**- STORAGE_SECRET** (str)\n\nThe access secret  key of the cloud storage provider\n\nNone for LOCAL\n\n**- STORAGE_CONTAINER** (str)\n\nThe *BUCKET NAME* for cloud storage providers\n\nFor *LOCAL* provider, this is the local directory path \n\n\n**STORAGE_ALLOWED_EXTENSIONS** (list)\n\nList of all extensions to allow\n\nExample: [\"png\", \"jpg\", \"jpeg\", \"mp3\"]\n\n**STORAGE_SERVER** (bool)\n\nFor *LOCAL* provider only. \n\nTrue to expose the files in the container so they can be accessed\n\nDefault: *True*\n\n**STORAGE_SERVER_URL** (str)\n\nFor *LOCAL* provider only.\n\nThe endpoint to access the files from the local storage. \n\nDefault: */files*\n\n---\n\n## API Documention\n\nFlask-Cloudy is a wrapper around Apache-Libcloud, the Storage class gives you access to Driver and Container of Apache-Libcloud.\n\n*Lexicon:*\n\nObject: A file or a file path. \n\nContainer: The main directory, or a bucket name containing all the objects\n\nProvider: The method \n\nStorage: \n\n### flask_cloudy.Storage\n\nThe **Storage** class allows you to access, upload, get an object from the Storage. \n\n#### Storage(provider, key=None, secret=None, container=None, allowed_extensions=None)\n\n- provider: the storage provider:\n\n    - LOCAL\n    - S3\n    - S3_US_WEST\n    - S3_US_WEST_OREGON\n    - S3_EU_WEST\n    - S3_AP_SOUTHEAST\n    - S3_AP_NORTHEAST\n    - GOOGLE_STORAGE\n    - AZURE_BLOBS\n    - CLOUDFILES\n\n- key: The access key of the cloud storage. None when provider is LOCAL\n\n- secret: The secret access key of the cloud storage. None when provider is LOCAL\n\n- container: \n\n     - For cloud storage, use the **BUCKET NAME** \n     \n     - For LOCAL provider, it's the directory path where to access the files \n     \n- allowed_extensions: List of extensions to upload to upload\n\n\n#### Storage.init_app(app)\n\nTo initiate the Storage via Flask config.\n\nIt will also setup a server endpoint when STORAGE_PROVIDER == LOCAL\n\n```py\n\n\tfrom flask import Flask, request\n\tfrom flask_cloudy import Storage\n\t\n\tapp = Flask(__name__)\n\t\n\t# Update the config \n\tapp.config.update({\n\t\t\"STORAGE_PROVIDER\": \"LOCAL\", # Can also be S3, GOOGLE_STORAGE, etc... \n\t\t\"STORAGE_KEY\": \"\",\n\t\t\"STORAGE_SECRET\": \"\",\n\t\t\"STORAGE_CONTAINER\": \"./\",  # a directory path for local, bucket name of cloud\n\t\t\"STORAGE_SERVER\": True,\n\t\t\"STORAGE_SERVER_URL\": \"/files\"\n\t})\n\t\n\t# Setup storage\n\tstorage = Storage()\n\tstorage.init_app(app) \n\t\n    @app.route(\"/upload\", methods=[\"POST\", \"GET\"]):\n    def upload():\n        if request.method == \"POST\":\n        \tfile = request.files.get(\"file\")\n            my_upload = storage.upload(file)\n            \n            # some useful properties\n            name = my_upload.name\n            extension = my_upload.extension\n            size = my_upload.size\n            url = my_upload.url\n            \n            return url\n        \n    # Pretending the file uploaded is \"my-picture.jpg\"    \n\t# it will return a url in the format: http://domain.com/files/my-picture.jpg\n```\t\n\n\n#### Storage.get(object_name)\n\nGet an object in the storage by name, relative to the container.\n\nIt will return an instance of **flask_cloudy.Object**\n\n- object_name: The name of the object.\n\nSome valid object names, they can contains slashes to indicate it's a directory\n\n\n    - file.txt\n    \n    - my_dir/file.txt\n    \n    - my_dir/sub_dir/file.txt\n\n.\n```py\n\tstorage = Storage(provider, key, secret, container)\n\tobject_name = \"hello.txt\"\n\tmy_object = storage.get(object_name)\n```\t\n\t\n\n#### Storage.upload(file, name=None, prefix=None, extension=[], overwrite=Flase, public=False, random_name=False)\n\nTo save or upload a file in the container\n\n- file: the string of the file location or a file object\n\n- name: to give the file a new name\n\n- prefix: a name to add in front of the file name. Add a slash at the end of \nprefix to make it a directory otherwise it will just append it to the name\n\n- extensions: list of extensions\n\n- overwrite: If True it will overwrite existing files, otherwise it will add a uuid in the file name to make it unique\n\n- public: Bool - To set the **acl** to *public-read* when True, *private* when False\n\n- random_name: Bool - To randomly create a unique name if `name` is None\n\n.\n```py\n\tstorage = Storage(provider, key, secret, container)\n\tmy_file = \"my_dir/readme.md\"\n```\t\n\t\t\n**1) Upload file + file name is the name of the uploaded file **\n```py\t\n\tstorage.upload(my_file)\t\n```\t\n\t\n**2) Upload file + file name is now `new_readme`. It will will keep the extension of the original file**\n```py\t\n\tstorage.upload(my_file, name=\"new_readme\")\n```\t\nThe uploaded file will be named: **new_readme.md**\n\t\n\t\n**3) Upload file to a different path using `prefix`**\n\t\n```py\t\n\tstorage.upload(my_file, name=\"new_readme\", prefix=\"my_dir/\")\n```\n\t\nnow the filename becomes **my_dir/new_readme.md**\n\nOn LOCAL it will create the directory *my_dir* if it doesn't exist. \n\n```py\t\n\tstorage.upload(my_file, name=\"new_readme\", prefix=\"my_new_path-\")\n```\n\t\nnow the filename becomes **my_new_path-new_readme.md**\n\nATTENTION: If you want the file to be place in a subdirectory, `prefix` must have the trailing slash\n \n\n**4a.) Public upload**\n```py\n\tstorage.upload(my_file, public=True)\n```\t\n\t\n**4b.) Private upload**\n```py\n\tstorage.upload(my_file, public=False)\n```\n**5) Upload + random name**\n```py\n    storage.upload(my_file, random_name=True)\n```    \n **6) Upload with external url***\n \n You can upload an item from the internet directly to your storage \n ```py\n    storage.upload(\"http://the.site.path.com/abc.png\")\n```    \nIt will save the image to your storage\n\n\n#### Storage.create(object_name, size=0, hash=None, extra=None, metda_data=None)\n\nExplicitly create an object that may exist already. Usually, when paramameters (name, size, hash, etc...) are already saved, let's say in the database, and you want Storage to manipulate the file. \n```py\n\tstorage = Storage(provider, key, secret, container)\n\texisting_name = \"holla.txt\"\n\texisting_size = \"8000\" # in bytes\n\tnew_object = storage.create(object_name=existing_name, size=existing_size)\n\t\n\t# Now I can do\n\turl = new_object.url \n\tsize = len(new_object)\n```\n\n#### Storage.use(container)\n\nA context manager to temporarily use a different container on the same provider\n```\n    storage = Storage(provider, key, secret, container)\n\t\n    with storage.use(another_container_name) as s3:\n        s3.upload(newfile)\n```\nIn the example above, it will upload the `newfile` to the new container name\n\n\n*It's Pythonic!!!*\n\n#### Iterate through all the objects in the container\n\nEach object is an instance on **flask_cloudy.Object**\n```py\n\tstorage = Storage(provider, key, secret, container)\n\tfor obj in storage:\n\t\tprint(obj.name)\n```\n#### Get the total objects in the container\n```py\n\tstorage = Storage(provider, key, secret, container)\n\ttotal_items = len(storage)\n```\n#### Check to see if an object exists in the container\n```py\n\tstorage = Storage(provider, key, secret, container)\n\tmy_file = \"hello.txt\"\n\t\n\tif my_file in storage:\n\t\tprint(\"File is in the storage\")\n```\n---\n\n\n### flask_cloudy.Object\n\nThe class **Object** is an entity of an object in the container.\n\nUsually, you will get a cloud object by accessing an object in the container.\n```py\n\tstorage = Storage(provider, key, secret, container)\n\tmy_object = storage.get(\"my_object.txt\")\n```\t\nProperties:\n\t\n#### Object.name \n\nThe name of the object\n\n\n#### Object.size\n\nThe size in bytes of the object\n\n\n#### Object.extension\n\nThe extension of the object\n\n\n#### Object.url\n\nReturn the url of the object\n\nOn LOCAL, it will return the url without the domain name ( ie: /files/my-file.jpg )\n\nFor cloud providers it will return the full url\n\n#### Object.full_url \n\nReturns the full url of the object\n\nSpecially for LOCAL provider, it will return the url with the domain.\n\nFor cloud providers, it will return the full url just like **Object.url**\n\n\n#### Object.secure_url \n\nReturn a secured url, with **https://** \n\n\n#### Object.path\n\nThe path of the object relative to the container\n \n#### Object.full_path\n\nFor Local, it will show the full path of the object, otherwise it just returns\nthe Object.path\n \n\n#### Object.provider_name \n\nThe provider name: ie: Local, S3,...\n\n\n#### Object.type \n\nThe type of the object, ie: IMAGE, AUDIO, TEXT,... OTHER\n\n\n#### Object.info\n\nReturns a dict of the object name, extension, url, etc. This can be saved in a DB\n\nMethods:\n\n#### Object.save_to(destination, name=None, overwrite=False, delete_on_failure=True)\n\nTo save the object to a local path \n\n- destination: The directory to save the object to\n\n- name: To rename the file in the local directory. Do not put the extension of the file, it will append automatically\n\n- overwrite: bool - To overwrite the file if it exists\n\n- delete_on_failure: bool - To delete the file it fails to save\n\n.\n```py\n\tstorage = Storage(provider, key, secret, container)\n\tmy_object = storage.get(\"my_object.txt\")\n\tmy_new_path = \"/my/new/path\"\n\tmy_new_file = my_object.save_to(my_new_path)\n\t\n\tprint(my_new_file) # Will print -\u003e /my/new/path/my_object.txt\n```\n\n#### Object.download_url(timeout=60, name=None)\n\nReturn a URL that triggers the browser download of the file. On cloud providers it will return a signed url.\n\n- timeout: int - The time in seconds to give access to the url\n\n- name: str - for LOCAL only, to rename the file being downloaded\n\n.\n```py\n\tstorage = Storage(provider, key, secret, container)\n\tmy_object = storage.get(\"my_object.txt\")\n\tdownload_url = my_object.download_url()\t\n\t\n\t# or with flask\n\n    @app.route(\"/download/\u003cpath:object_name\u003e\"):\n    def download(object_name):\n        my_object = storage.get(object_name)\n        if my_object:\n        \tdownload_url = my_object.download_url()\n        \treturn redirect(download_url)\n        else:\t\n        \tabort(404, \"File doesn't exist\")\n``` \n\n---\n\nI hope you find this library useful, enjoy!\n\n\nMardix :) \n\n---\n\nLicense: MIT - Copyright 2017 Mardix\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmardix%2Fflask-cloudy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmardix%2Fflask-cloudy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmardix%2Fflask-cloudy/lists"}