Giter VIP home page Giter VIP logo

bifrost's Introduction

Bifrost

Rainbow bridge for shipping your files to any cloud storage service with the same function calls.

Table of contents

Problem Statement

Many projects need to store files in the cloud and different projects might use different cloud storage providers or, sometimes, multiple cloud providers all at once. Using different SDKs with different implementations for each provider can be tedious and time-consuming. Bifrost aims to simplify the process of working with multiple cloud storage providers by providing a consistent API for all of them.

To gain a better understanding of how Bifrost addresses this issue, let's take you on a ride with Thor by comparing two different code samples for working with Google Cloud Storage and Pinata Cloud in a single project: one using a conventional approach and the other using Bifrost.

Google Cloud Storage using GCS SDK

Without Bifrost, the process of uploading a file to GCS using the Google Cloud Storage client library for Go would typically involve the following steps:

package main

import (
	"context"
	"fmt"
	"io"
	"log"

	"cloud.google.com/go/storage"
)

func main() {
	ctx := context.Background()

	// create a client
	client, err := storage.NewClient(ctx)
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}
	defer client.Close()

	// open the file you want to upload
	file, err := os.Open("path/to/your/file")
	if err != nil {
		log.Fatalf("Failed to open file: %v", err)
	}
	defer file.Close()

	// create a bucket object
	bucket := client.Bucket("your-bucket-name")

	// create an object handle
	object := bucket.Object("destination/file/name")

	// create a writer to upload the file
	writer := object.NewWriter(ctx)

	// copy the contents of the file to the object
	if _, err := io.Copy(writer, file); err != nil {
		log.Fatalf("Failed to upload file: %v", err)
	}

	// close the writer to finalize the upload
	if err := writer.Close(); err != nil {
		log.Fatalf("Failed to close writer: %v", err)
	}

	fmt.Println("File uploaded successfully!")
}

Pinata Cloud using Pinata API

...and for Pinata Cloud, the usual way of uploading a file in Go would be something along the following steps:

package main

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"os"
)

func main() {
	// Set the API key and secret key
	apiKey := "your-api-key"
	secretApiKey := "your-secret-api-key"

	// Open the file to be uploaded
	file, err := os.Open("path/to/file")
	if err != nil {
		fmt.Println("Error opening file:", err)
		return
	}
	defer file.Close()

	// Prepare the request body
	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)
	part, err := writer.CreateFormFile("file", file.Name())
	if err != nil {
		fmt.Println("Error creating form file:", err)
		return
	}
	_, err = io.Copy(part, file)
	if err != nil {
		fmt.Println("Error copying file:", err)
		return
	}
	err = writer.Close()
	if err != nil {
		fmt.Println("Error closing writer:", err)
		return
	}

	// Prepare the request
	url := "https://api.pinata.cloud/pinning/pinFileToIPFS"
	req, err := http.NewRequest("POST", url, body)
	if err != nil {
		fmt.Println("Error creating request:", err)
		return
	}
	req.Header.Add("Content-Type", writer.FormDataContentType())
	req.Header.Add("pinata_api_key", apiKey)
	req.Header.Add("pinata_secret_api_key", secretApiKey)

	// Send the request
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("Error sending request:", err)
		return
	}
	defer resp.Body.Close()

	// Read the response body
	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Error reading response:", err)
		return
	}

	// Print the response
	fmt.Println(string(respBody))
}

We can already see the challenges of the conventional methods since they require you to learn to use multiple packages with separate implementation patterns. Now this is why Bifrost comes in! With Bifrost, you can mount rainbow bridges to the providers you want and use the same set of functions to upload files through any of these mounted bridges. This makes it much easier to work with multiple providers and streamlines the development process to just one learning curve.

Now, let's see how we can revamp the two samples above into something much more exciting with Bifrost.

Using Bifrost

package main

import (
	"fmt"
	"os"
	"github.com/opensaucerer/bifrost"
)

// mount a bridge to gcs
gcsBridge, _ := bifrost.NewRainbowBridge(&bifrost.BridgeConfig{
	DefaultBucket:   "bifrost",
	DefaultTimeout:  10,
	Provider:        bifrost.GoogleCloudStorage,
	CredentialsFile: "/path/to/service/account/json", // this is not required if you are using google's default credentials
	EnableDebug:     true,
	PublicRead:      true,
})
defer gcsBridge.Disconnect()
fmt.Printf("Connected to %s\n", gcsBridge.Config().Provider)

// mount a bridge to Pinata
pinataBridge, _ := bifrost.NewRainbowBridge(&bifrost.BridgeConfig{
	Provider:    bifrost.PinataCloud,
	PinataJWT:   os.Getenv("PINATA_JWT"),
	EnableDebug: true,
	PublicRead:  true,
})
defer pinataBridge.Disconnect()
fmt.Printf("Connected to %s\n", pinataBridge.Config().Provider)

// upload a file to gcs using the bridge
guf, _ := gcsBridge.UploadFile(bifrost.File{
	Path:     "../shared/image/aand.png",
	Filename: "a_and_ampersand.png",
	Options: map[string]interface{}{
		bifrost.OptMetadata: map[string]string{
			"originalname": "aand.png",
		},
	},
})
fmt.Printf("Uploaded file %s to GCS at: %s\n", guf.Name, guf.Preview)

// upload a file to Pinata using the bridge
puf, _ := bridge.UploadFile(bifrost.File{
	Path:     "../shared/image/aand.png",
	Filename: "pinata_aand.png",
	Options: map[string]interface{}{
		bifrost.OptPinata: map[string]interface{}{
			"cidVersion": 1,
		},
		bifrost.OptMetadata: map[string]string{
			"originalname": "aand.png",
		},
	},
})
fmt.Printf("Uploaded file %s to Pinata at: %s\n", puf.Name, puf.Preview)

The above example clearly demonstrates the speed, simplicity, and ease of use that Bifrost offers. Now you know what it feels like to ride with Thor!

Installation

To install the Bifrost package, run the following command in your terminal:

go get github.com/opensaucerer/bifrost

Usage

If you want to learn more about how Bifrost is creating different methods to make it easier to use different cloud providers, you can follow these links:

Variants

Bifrost also exists in other forms and languages and you are free to start a new variant of bifrost in any other form or language of your choice. For now, below are the know variants of bifrost.

Contributing

Bifrost is an open source project and we welcome contributions of all kinds. Please read our contributing guide to learn about our development process, how to propose bug fixes and improvements, and how to build and test your changes to Bifrost.

License

Bifrost is MIT licensed.

Changelog

See changelog for more details.

Contributors

Made with contrib.rocks.

bifrost's People

Contributors

opensaucerer avatar marzz29 avatar funmi4194 avatar ceofred avatar showbaba avatar emmrys-jay avatar dark-enstein avatar

Stargazers

 avatar Daniel Benjamin avatar Damilola Dolor avatar akerele abraham avatar Salman Musa avatar Serge avatar David Wooldridge avatar Diretnan Domnan avatar Ayo Alonge avatar  avatar Matt Mahdieh avatar Andrew Garner avatar snowmerak avatar Edwin Walela avatar Antares avatar Can Evgin avatar Jeremiah Faluyi avatar Wayan jimmy avatar Josue Kouka avatar Ron Green avatar Jim Myhrberg avatar Juan Pablo Villaseca Carrasco avatar Karthik avatar Alexfilus avatar  avatar  avatar  avatar Jérôme Foray avatar astrolemonade avatar Tommy Smith avatar Márk Bartos avatar Tai Groot avatar Ifihanagbara Olusheye avatar  avatar Sayo Paul avatar Izu Izu avatar Ayotomide avatar Joseph Tsegen avatar Dev. Abdul avatar Sikiru Ademola avatar  avatar Nator Verinumbe avatar  Mosadomi Peter Olumide avatar  avatar  avatar developed avatar David Horjet avatar Bernard.O avatar Ayobami Oki avatar Chinazam Ikechukwu Enoch avatar PeterAkande avatar  avatar Olatokunbo David avatar Watson code  avatar EzeFrancis avatar Sobowale Olumuyiwa avatar  avatar

Watchers

Shoyombo Raphael avatar Kostas Georgiou avatar  avatar  avatar Sikiru Ademola avatar

bifrost's Issues

Update doc.md of each provider

Title

Update documentation for cloud service providers with different methods for using Bifrost

Description

The current documentation for Bifrost only provides a general guide on how to use the tool. To ensure that users have a better understanding of how to use Bifrost with different cloud service providers, we need to update the documentation to include detailed guides for each provider.

This issue aims to update the documentation for each cloud service provider that contains different methods on how to use Bifrost. The updated documentation will provide users with a comprehensive guide on how to use Bifrost with their preferred cloud service provider.

To achieve this, we will create a new doc file for each provider in the package folder. These files will contain detailed instructions on how to mount a bridge for the provider and how to use each method available for such provider. All the methods actually... (UploadFile, UploadMultiFile, Disconnect, Config, IsConnected, etc...)

The following providers will be included:

  • Google Cloud Storage (GCS)

  • Amazon Web Services (AWS) S3

  • Pinata Cloud

Each provider doc file will include the following sections:

  • Introduction to Bifrost and the provider
  • Prerequisites for using Bifrost with the provider
  • Configuring Bifrost for the provider
  • Methods for using Bifrost with the provider
  • Troubleshooting common issues

By updating the documentation with detailed guides for each cloud service provider, users will have a better understanding of how to use Bifrost effectively with their preferred provider. This will improve the overall user experience and make Bifrost a more useful tool for developers.

This issue will require collaboration from the community to ensure that the documentation is accurate and up-to-date. Contributors are welcome to submit pull requests with improvements to the documentation for any provider.

Added configuration to allow support for async operations

A new field called UseAsync should be added to the BridgeConfig struct with a bool value.
With this inclusion requires also the addition of quit and done channels to the UploadedFile struct returned during any call to the UploadFile function of any rainbow bridge.
These channels allow Bifrost to signal the completion of async operations while also allowing users to signal the termination of async operations, if necessary.

Adding feature to delete an object from multiple buckets on google cloud storage

This issue will address the feature to delete an object from multiple buckets on google cloud storage

first step:
The BridgeConfig struct would include extra fields as defined below

type BridgeConfig struct {
	.....
        // Buckets specifics the list of bucket names to interact with
	Buckets []string
	// Object specifics an object name in a bucket to interact with
	Object string
}

The DeleteGCSobject takes an instance of BridgeConfig struct which contains the gcs credentials file, buckets field (array of buckets to delete the object from), object field (object to delete).

Update product description, problem statement, installation and usage instructions, and add a table of contents in README.md

Issue Descriptions

  1. Product description: The current description of the project is insufficient and needs improvement to better convey its purpose and features to potential users and contributors.
  2. Problem statement: The problem statement is clear and concise; however, the description could benefit from additional information to provide a better understanding of the project's goals and objectives.
  3. Installation guide: The installation guide is lacking a clear prompt that explains what the code would do if the user follows the instructions, leaving the user uncertain about the outcome of their actions.
  4. Usage Instructions: The current README file includes usage instructions for three different cloud providers which can be overwhelming for users and contributors, which might not provide a clear understanding of how to use the code. Additionally, there is no explanation of the code that was put there, which could lead to confusion or errors when trying to use the code.
  5. Table of Contents: I would like to suggest adding a table of contents to the README for better readability and easier navigation for users. This will help users quickly find the information they need and navigate to the relevant sections without having to read through the entire document.

Proposed Solution

  1. Product description: Rewrite the description to include a clear and concise overview of the project's purpose, features, and benefits.
  2. Problem statement: Expand the problem statement section to provide more information on the project's objectives, including the specific challenges it aims to address.
  3. Installation guide: Add a clear prompt at the beginning of the installation guide that explains what the code will do if the user follows the instructions.
  4. Usage Instructions: To make it easier for users and contributors to understand how to use the product, it would be helpful to reduce the usage examples to one cloud provider and provide detailed explanations of how to use the product before including the code. This will allow users to have a clear understanding of what they are doing and help to prevent errors or confusion.
  5. Table of Contents: Create a table of contents at the beginning of the README, with clickable links to each section of the document. This will make it easier for users to navigate the document and find the information they need quickly.

Additional Information

  • This change does not affect any existing functionality or code; it only updates the README file.
  • The CONTRIBUTING.md file would also reflect these changes.

Allow for uploading multiple files to GCS

Description

  • Create a method to allow uploading multiple files to Google Cloud Storage.
  • Add method to RainbowBridge interface.
  • Write tests for the method.

MethodName: UploadMultiFile

UploadFolder support for Pinata cloud

func UploadFolder(path string, options map[string]interface{}) ([]*types.UploadedFile, error) {
	return nil, nil
}

We'll need a function that efficiently walks the given directory in order to upload the files to Pinata...I haven't checked how Pinata folder upload works but I'm thinking there might be a need to make some updates to the func (c *Client) PostForm() method present in the request package.

add some validations

add validations to some inputs like filename and file path (should contain a file extension), this might cause the file URL to be invalid

Recommend Projects

  • React photo React

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

  • Vue.js photo Vue.js

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

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

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

Recommend Topics

  • javascript

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

  • web

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

  • server

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

  • Machine learning

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

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

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

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.