Commit 7d7572af authored by tavit ohanian's avatar tavit ohanian

Merge branch 'port-2021-05-14'

parents f4a3c65a a77cf9b7
Pipeline #339 passed with stages
in 21 seconds
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
stages:
- build
- test
variables:
BUILD_DIR: "/tmp/$CI_CONCURRENT_PROJECT_ID"
before_script:
- mkdir -p $BUILD_DIR/src
- cd $BUILD_DIR/src
- if [ -d $CI_PROJECT_DIR ]
- then
- echo "soft link $CI_PROJECT_DIR exists"
- else
- echo "creating soft link $CI_PROJECT_DIR"
- ln -s $CI_PROJECT_DIR
- fi
- cd $CI_PROJECT_DIR
build:
stage: build
tags:
- testing
script:
- echo $CI_JOB_STAGE
- go build
test:
stage: test
tags:
- testing
script:
- echo $CI_JOB_STAGE
- go test -cover
coverage: '/coverage: \d+.\d+% of statements/'
language: go
go:
- 1.14.x
install:
- go get -d -v .
script:
- go build -v ./
The software contents of this repository are Copyright (c) Protocol Labs,
Licensed under the `Permissive License Stack`, meaning either of:
- Apache-2.0 Software License: https://www.apache.org/licenses/LICENSE-2.0
([...4tr2kfsq](https://gateway.ipfs.io/ipfs/bafkreiankqxazcae4onkp436wag2lj3ccso4nawxqkkfckd6cg4tr2kfsq))
- MIT Software License: https://opensource.org/licenses/MIT
([...vljevcba](https://gateway.ipfs.io/ipfs/bafkreiepofszg4gfe2gzuhojmksgemsub2h4uy2gewdnr35kswvljevcba))
You may not use the contents of this repository except in compliance
with one of the listed Licenses. For an extended clarification of the
intent behind the choice of Licensing please refer to
https://protocol.ai/blog/announcing-the-permissive-license-stack/
Unless required by applicable law or agreed to in writing, software
distributed under the terms listed in this notice is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
either express or implied. See each License for the specific language
governing permissions and limitations under that License.
<!--- SPDX-License-Identifier: Apache-2.0 OR MIT -->
`SPDX-License-Identifier: Apache-2.0 OR MIT`
\ No newline at end of file
# go-pinning-service-http-client # go-pinning-service-http-client
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://protocol.ai)
[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](https://ipfs.io/)
[![](https://img.shields.io/badge/status-draft-yellow.svg?style=flat-square)](https://github.com/ipfs/specs/#understanding-the-meaning-of-the-spec-badges-and-their-lifecycle)
An IPFS Pinning Service HTTP Client
> This repo is contains a reference implementation of a client for the [IPFS Pinning Services API Spec](https://github.com/ipfs/pinning-services-api-spec)
## Lead Maintainer
[Adin Schmahmann](https://github.com/aschmahmann)
## Updating Pinning Service Spec
Download the openapi-generator from https://github.com/OpenAPITools/openapi-generator and generate the code using:
Current code generated with: openapi-generator 5.0.0-beta
```
openapi-generator generate -g go-experimental -i https://raw.githubusercontent.com/ipfs/pinning-services-api-spec/master/ipfs-pinning-service.yaml -o openapi
rm openapi/go.mod openapi/go.sum
```
Notes:
Due to https://github.com/OpenAPITools/openapi-generator/issues/7473 the code generator the http error codes processing
may need some manual editing.
`go-experimental` is becoming mainstream and so in later versions will be replaced with `go`
## Contributing
Contributions are welcome! This repository is part of the IPFS project and therefore governed by our [contributing guidelines](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md).
## License
[SPDX-License-Identifier: Apache-2.0 OR MIT](LICENSE.md)
package go_pinning_service_http_client
import (
"context"
"fmt"
"github.com/pkg/errors"
"net/http"
"time"
"gitlab.dms3.io/dms3/public/go-cid"
"gitlab.dms3.io/dms3/public/go-pinning-service-http-client/openapi"
"github.com/multiformats/go-multiaddr"
"github.com/multiformats/go-multibase"
logging "gitlab.dms3.io/dms3/public/go-log/v2"
)
var logger = logging.Logger("pinning-service-http-client")
const UserAgent = "go-pinning-service-http-client"
type Client struct {
client *openapi.APIClient
}
func NewClient(url, bearerToken string) *Client {
config := openapi.NewConfiguration()
config.UserAgent = UserAgent
bearer := fmt.Sprintf("Bearer %s", bearerToken)
config.AddDefaultHeader("Authorization", bearer)
config.Servers = openapi.ServerConfigurations{
openapi.ServerConfiguration{
URL: url,
},
}
return &Client{client: openapi.NewAPIClient(config)}
}
// TODO: We should probably make sure there are no duplicates sent
type lsSettings struct {
cids []string
name string
status []Status
before *time.Time
after *time.Time
limit *int32
meta map[string]string
}
type LsOption func(options *lsSettings) error
var PinOpts = pinOpts{}
type pinOpts struct {
pinLsOpts
pinAddOpts
}
type pinLsOpts struct{}
func (pinLsOpts) FilterCIDs(cids ...cid.Cid) LsOption {
return func(options *lsSettings) error {
enc := getCIDEncoder()
for _, c := range cids {
options.cids = append(options.cids, c.Encode(enc))
}
return nil
}
}
const maxNameSize = 255
func (pinLsOpts) FilterName(name string) LsOption {
return func(options *lsSettings) error {
if len(name) > maxNameSize {
return fmt.Errorf("name cannot be longer than %d", maxNameSize)
}
options.name = name
return nil
}
}
func (pinLsOpts) FilterStatus(statuses ...Status) LsOption {
return func(options *lsSettings) error {
for _, s := range statuses {
valid := false
for _, existing := range validStatuses {
if existing == s {
valid = true
break
}
}
if !valid {
return fmt.Errorf("invalid status %s", s)
}
}
options.status = append(options.status, statuses...)
return nil
}
}
func (pinLsOpts) FilterBefore(t time.Time) LsOption {
return func(options *lsSettings) error {
options.before = &t
return nil
}
}
func (pinLsOpts) FilterAfter(t time.Time) LsOption {
return func(options *lsSettings) error {
options.after = &t
return nil
}
}
const recordLimit = 1000
const defaultLimit = 10
func (pinLsOpts) Limit(limit int) LsOption {
return func(options *lsSettings) error {
if limit > recordLimit {
return fmt.Errorf("limit exceeded maximum record limit of %d", recordLimit)
}
limitCasted := int32(limit)
options.limit = &limitCasted
return nil
}
}
func (pinLsOpts) LsMeta(meta map[string]string) LsOption {
return func(options *lsSettings) error {
options.meta = meta
return nil
}
}
type pinResults = openapi.PinResults
func (c *Client) Ls(ctx context.Context, opts ...LsOption) (chan PinStatusGetter, chan error) {
res := make(chan PinStatusGetter, 1)
errs := make(chan error, 1)
settings := new(lsSettings)
for _, o := range opts {
if err := o(settings); err != nil {
close(res)
errs <- err
close(errs)
return res, errs
}
}
go func() {
defer close(errs)
defer close(res)
for {
pinRes, err := c.lsInternal(ctx, settings)
if err != nil {
errs <- err
return
}
results := pinRes.GetResults()
for _, r := range results {
select {
case res <- &pinStatusObject{r}:
case <-ctx.Done():
errs <- ctx.Err()
return
}
}
if int(pinRes.Count) == len(results) {
return
}
oldestResult := pinRes.Results[len(pinRes.Results)-1]
settings.before = &oldestResult.Created
}
}()
return res, errs
}
func (c *Client) LsSync(ctx context.Context, opts ...LsOption) ([]PinStatusGetter, error) {
resCh, errCh := c.Ls(ctx, opts...)
var res []PinStatusGetter
for r := range resCh {
res = append(res, r)
}
return res, <-errCh
}
// Manual version of Ls that returns a single batch of results and int with total count
func (c *Client) LsBatchSync(ctx context.Context, opts ...LsOption) ([]PinStatusGetter, int, error) {
var res []PinStatusGetter
settings := new(lsSettings)
for _, o := range opts {
if err := o(settings); err != nil {
return nil, 0, err
}
}
pinRes, err := c.lsInternal(ctx, settings)
if err != nil {
return nil, 0, err
}
results := pinRes.GetResults()
for _, r := range results {
res = append(res, &pinStatusObject{r})
}
return res, int(pinRes.Count), nil
}
func (c *Client) lsInternal(ctx context.Context, settings *lsSettings) (pinResults, error) {
getter := c.client.PinsApi.PinsGet(ctx)
if len(settings.cids) > 0 {
getter = getter.Cid(settings.cids)
}
if len(settings.status) > 0 {
statuses := make([]openapi.Status, len(settings.status))
for i := 0; i < len(statuses); i++ {
statuses[i] = openapi.Status(settings.status[i])
}
getter = getter.Status(statuses)
}
if settings.limit == nil {
getter = getter.Limit(defaultLimit)
} else {
getter = getter.Limit(*settings.limit)
}
if len(settings.name) > 0 {
getter = getter.Name(settings.name)
}
if settings.before != nil {
getter = getter.Before(*settings.before)
}
if settings.after != nil {
getter = getter.After(*settings.after)
}
if settings.meta != nil {
getter = getter.Meta(settings.meta)
}
// TODO: Ignoring HTTP Response OK?
results, httpresp, err := getter.Execute()
if err != nil {
err := httperr(httpresp, err)
return pinResults{}, err
}
return results, nil
}
// TODO: We should probably make sure there are no duplicates sent
type addSettings struct {
cid string
name string
origins []string
meta map[string]string
}
type AddOption func(options *addSettings) error
type pinAddOpts struct{}
func (pinAddOpts) WithName(name string) AddOption {
return func(options *addSettings) error {
if len(name) > maxNameSize {
return fmt.Errorf("name cannot be longer than %d", maxNameSize)
}
options.name = name
return nil
}
}
func (pinAddOpts) WithOrigins(origins ...multiaddr.Multiaddr) AddOption {
return func(options *addSettings) error {
for _, o := range origins {
options.origins = append(options.origins, o.String())
}
return nil
}
}
func (pinAddOpts) AddMeta(meta map[string]string) AddOption {
return func(options *addSettings) error {
options.meta = meta
return nil
}
}
func (c *Client) Add(ctx context.Context, cid cid.Cid, opts ...AddOption) (PinStatusGetter, error) {
settings := new(addSettings)
for _, o := range opts {
if err := o(settings); err != nil {
return nil, err
}
}
adder := c.client.PinsApi.PinsPost(ctx)
p := openapi.Pin{
Cid: cid.Encode(getCIDEncoder()),
}
if len(settings.origins) > 0 {
p.SetOrigins(settings.origins)
}
if settings.meta != nil {
p.SetMeta(settings.meta)
}
if len(settings.name) > 0 {
p.SetName(settings.name)
}
result, httpresp, err := adder.Pin(p).Execute()
if err != nil {
err := httperr(httpresp, err)
return nil, err
}
return &pinStatusObject{result}, nil
}
func (c *Client) GetStatusByID(ctx context.Context, pinID string) (PinStatusGetter, error) {
getter := c.client.PinsApi.PinsRequestidGet(ctx, pinID)
result, httpresp, err := getter.Execute()
if err != nil {
err := httperr(httpresp, err)
return nil, err
}
return &pinStatusObject{result}, nil
}
func (c *Client) DeleteByID(ctx context.Context, pinID string) error {
deleter := c.client.PinsApi.PinsRequestidDelete(ctx, pinID)
httpresp, err := deleter.Execute()
if err != nil {
err := httperr(httpresp, err)
return err
}
return nil
}
func (c *Client) Replace(ctx context.Context, pinID string, cid cid.Cid, opts ...AddOption) (PinStatusGetter, error) {
settings := new(addSettings)
for _, o := range opts {
if err := o(settings); err != nil {
return nil, err
}
}
adder := c.client.PinsApi.PinsRequestidPost(ctx, pinID)
p := openapi.Pin{
Cid: cid.Encode(getCIDEncoder()),
}
if len(settings.origins) > 0 {
p.SetOrigins(settings.origins)
}
if settings.meta != nil {
p.SetMeta(settings.meta)
}
if len(settings.name) > 0 {
p.SetName(settings.name)
}
result, httpresp, err := adder.Pin(p).Execute()
if err != nil {
err := httperr(httpresp, err)
return nil, err
}
return &pinStatusObject{result}, nil
}
func getCIDEncoder() multibase.Encoder {
enc, err := multibase.NewEncoder(multibase.Base32)
if err != nil {
panic(err)
}
return enc
}
func httperr(resp *http.Response, e error) error {
oerr, ok := e.(openapi.GenericOpenAPIError)
if ok {
ferr, ok := oerr.Model().(openapi.Failure)
if ok {
return errors.Wrapf(e, "reason: %q, details: %q", ferr.Error.GetReason(), ferr.Error.GetDetails())
}
}
if resp == nil {
return errors.Wrapf(e, "empty response from remote pinning service")
}
return errors.Wrapf(e, "remote pinning service returned http error %d", resp.StatusCode)
}
package main
import (
"context"
"fmt"
"os"
"time"
"gitlab.dms3.io/dms3/public/go-cid"
pinclient "gitlab.dms3.io/dms3/public/go-pinning-service-http-client"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
url, ok := os.LookupEnv("PS_URL")
if !ok {
panic("No Pinning Service URL found")
}
key, ok := os.LookupEnv("PS_KEY")
if !ok {
panic("No Pinning Service API Key found")
}
c := pinclient.NewClient(url, key)
dms3PgCid, err := cid.Parse("bafybeiayvrj27f65vbecspbnuavehcb3znvnt2strop2rfbczupudoizya")
if err != nil {
panic(err)
}
libp2pCid, err := cid.Parse("bafybeiejgrxo4p4uofgfzvlg5twrg5w7tfwpf7aciiswfacfbdpevg2xfy")
if err != nil {
panic(err)
}
_ = dms3PgCid
listPins(ctx, c)
fmt.Println("Adding libp2p home page")
ps, err := c.Add(ctx, libp2pCid, pinclient.PinOpts.WithName("libp2p"))
if err == nil {
fmt.Printf("PinStatus: %v \n", ps)
} else {
fmt.Println(err)
}
listPins(ctx, c)
fmt.Println("Check on pin status")
if ps == nil {
panic("Skipping pin status check because the pin is null")
}
var pinned bool
for !pinned {
status, err := c.GetStatusByID(ctx, ps.GetRequestId())
if err == nil {
fmt.Println(status.GetStatus())
pinned = status.GetStatus() == pinclient.StatusPinned
} else {
fmt.Println(err)
}
time.Sleep(time.Millisecond * 500)
}
listPins(ctx, c)
fmt.Println("Delete pin")
err = c.DeleteByID(ctx, ps.GetRequestId())
if err == nil {
fmt.Println("Successfully deleted pin")
} else {
fmt.Println(err)
}
listPins(ctx, c)
}
func listPins(ctx context.Context, c *pinclient.Client) {
fmt.Println("List all pins")
pins, err := c.LsSync(ctx)
if err != nil {
fmt.Println(err)
} else {
for _, p := range pins {
fmt.Printf("Pin: %v \n", p)
}
}
}
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/ipfs/go-cid v0.0.7 h1:ysQJVJA3fNDF1qigJbsSQOdjhVLsOEoPdh0+R97k3jY=
github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU=
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g=
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771 h1:MHkK1uRtFbVqvAgvWxafZe54+5uBxLluGylDiKgdhwo=
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc=
github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI=
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4=
github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM=
github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y=
github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI=
github.com/multiformats/go-multiaddr v0.3.1 h1:1bxa+W7j9wZKTZREySx1vPMs2TqrYWjVZ7zE6/XLG1I=
github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc=
github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA=
github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk=
github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc=
github.com/multiformats/go-multihash v0.0.13 h1:06x+mk/zj1FoMsgNejLpy6QTvJqlSt/BhLEy87zidlc=
github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
github.com/multiformats/go-multihash v0.0.14 h1:QoBceQYQQtNUuf6s7wHxnE2c8bhbMqhfGzNI032se/I=
github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
github.com/multiformats/go-varint v0.0.5 h1:XVZwSo04Cs3j/jS0uAEPpT3JY6DzMcVLLoWOSnCxOjg=
github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY=
github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
gitlab.dms3.io/dms3/public/go-cid v0.0.1 h1:qs4dtkDigcLGY/58dIZaFjKLt+orrTcmTBvtqaM3570=
gitlab.dms3.io/dms3/public/go-cid v0.0.1/go.mod h1:GQw3gc4CSrFY+aX6M+OBQDlg0p5/eQJoRrayaZzkAOQ=
gitlab.dms3.io/dms3/public/go-log/v2 v2.0.0 h1:wuQlyeKop/bBd5y4m/GARriSgX9VZOIWv2Lo1h8m2/c=
gitlab.dms3.io/dms3/public/go-log/v2 v2.0.0/go.mod h1:eIsr0zyB2Ny/Tu0TdTeI1CHMRwaBg3q58LL2PKxEk34=
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
package go_pinning_service_http_client
import (
"encoding/json"
"fmt"
"time"
"github.com/multiformats/go-multiaddr"
"gitlab.dms3.io/dms3/public/go-cid"
"gitlab.dms3.io/dms3/public/go-pinning-service-http-client/openapi"
)
// PinGetter Getter for Pin object
type PinGetter interface {
fmt.Stringer
json.Marshaler
// CID to be pinned recursively
GetCid() cid.Cid
// Optional name for pinned data; can be used for lookups later
GetName() string
// Optional list of multiaddrs known to provide the data
GetOrigins() []string
// Optional metadata for pin object
GetMeta() map[string]string
}
type pinObject struct {
openapi.Pin
}
func (p *pinObject) MarshalJSON() ([]byte, error) {
var originsStr string
if o := p.GetOrigins(); o != nil {
originsBytes, err := json.Marshal(o)
if err == nil {
originsStr = string(originsBytes)
}
}
metaStr := "{}"
if meta := p.GetMeta(); meta != nil {
metaBytes, err := json.Marshal(meta)
if err == nil {
metaStr = string(metaBytes)
}
}
str := fmt.Sprintf("{ \"Cid\" : \"%v\", \"Name\" : \"%s\", \"Origins\" : %v, \"Meta\" : %v }",
p.GetCid(), p.GetName(), originsStr, metaStr)
return []byte(str), nil
}
func (p *pinObject) String() string {
marshalled, err := json.MarshalIndent(p, "", "\t")
if err != nil {
return ""
}
return string(marshalled)
}
func (p *pinObject) GetCid() cid.Cid {
c, err := cid.Parse(p.Pin.Cid)
if err != nil {
return cid.Undef
}
return c
}
type Status string
const (
StatusUnknown Status = ""
StatusQueued Status = Status(openapi.QUEUED)
StatusPinning Status = Status(openapi.PINNING)
StatusPinned Status = Status(openapi.PINNED)
StatusFailed Status = Status(openapi.FAILED)
)
func (s Status) String() string {
switch s {
case StatusQueued, StatusPinning, StatusPinned, StatusFailed:
return string(s)
default:
return string(StatusUnknown)
}
}
var validStatuses = []Status{"queued", "pinning", "pinned", "failed"}
// PinStatusGetter Getter for Pin object with status
type PinStatusGetter interface {
fmt.Stringer
json.Marshaler
// Globally unique ID of the pin request; can be used to check the status of ongoing pinning, modification of pin object, or pin removal
GetRequestId() string
GetStatus() Status
// Immutable timestamp indicating when a pin request entered a pinning service; can be used for filtering results and pagination
GetCreated() time.Time
GetPin() PinGetter
// List of multiaddrs designated by pinning service for transferring any new data from external peers
GetDelegates() []multiaddr.Multiaddr
// Optional info for PinStatus response
GetInfo() map[string]string
}
type pinStatusObject struct {
openapi.PinStatus
}
func (p *pinStatusObject) GetDelegates() []multiaddr.Multiaddr {
delegates := p.PinStatus.GetDelegates()
addrs := make([]multiaddr.Multiaddr, 0, len(delegates))
for _, d := range delegates {
a, err := multiaddr.NewMultiaddr(d)
if err != nil {
logger.Errorf("returned delegate is an invalid multiaddr: %w", err)
continue
}
addrs = append(addrs, a)
}
return addrs
}
func (p *pinStatusObject) GetPin() PinGetter {
return &pinObject{p.Pin}
}
func (p *pinStatusObject) GetStatus() Status {
return Status(p.PinStatus.GetStatus())
}
func (p *pinStatusObject) GetRequestId() string {
return p.GetRequestid()
}
func (p *pinStatusObject) MarshalJSON() ([]byte, error) {
var delegatesStr string
if d := p.GetDelegates(); d != nil {
delegatesBytes, err := json.Marshal(d)
if err == nil {
delegatesStr = string(delegatesBytes)
}
}
infoStr := "{}"
if info := p.GetInfo(); info != nil {
infoBytes, err := json.Marshal(info)
if err == nil {
infoStr = string(infoBytes)
}
}
str := fmt.Sprintf("{\"Pin\" : %v, \"RequestID\" : \"%s\", \"Status\" : \"%s\", \"Created\" : \"%v\", \"Delegates\" : %v, \"Info\" : %v }",
p.GetPin(), p.GetRequestId(), p.GetStatus(), p.GetCreated(), delegatesStr, infoStr)
return []byte(str), nil
}
func (p *pinStatusObject) String() string {
marshalled, err := json.MarshalIndent(p, "", "\t")
if err != nil {
return ""
}
return string(marshalled)
}
# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.
# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
#ApiClient.cs
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md
.gitignore
.openapi-generator-ignore
.travis.yml
README.md
api/openapi.yaml
api_pins.go
client.go
configuration.go
docs/Failure.md
docs/FailureError.md
docs/Pin.md
docs/PinResults.md
docs/PinStatus.md
docs/PinsApi.md
docs/Status.md
git_push.sh
go.mod
go.sum
model_failure.go
model_failure_error.go
model_pin.go
model_pin_results.go
model_pin_status.go
model_status.go
response.go
utils.go
5.0.0-beta
\ No newline at end of file
# Go API client for openapi
## About this spec
The IPFS Pinning Service API is intended to be an implementation-agnostic API&#x3a;
- For use and implementation by pinning service providers
- For use in client mode by IPFS nodes and GUI-based applications
> **Note**: while ready for implementation, this spec is still a work in progress! 🏗️ **Your input and feedback are welcome and valuable as we develop this API spec. Please join the design discussion at [github.com/ipfs/pinning-services-api-spec](https://github.com/ipfs/pinning-services-api-spec).**
# Schemas
This section describes the most important object types and conventions.
A full list of fields and schemas can be found in the `schemas` section of the [YAML file](https://github.com/ipfs/pinning-services-api-spec/blob/master/ipfs-pinning-service.yaml).
## Identifiers
### cid
[Content Identifier (CID)](https://docs.ipfs.io/concepts/content-addressing/) points at the root of a DAG that is pinned recursively.
### requestid
Unique identifier of a pin request.
When a pin is created, the service responds with unique `requestid` that can be later used for pin removal. When the same `cid` is pinned again, a different `requestid` is returned to differentiate between those pin requests.
Service implementation should use UUID, `hash(accessToken,Pin,PinStatus.created)`, or any other opaque identifier that provides equally strong protection against race conditions.
## Objects
### Pin object
![pin object](https://bafybeideck2fchyxna4wqwc2mo67yriokehw3yujboc5redjdaajrk2fjq.ipfs.dweb.link/pin.png)
The `Pin` object is a representation of a pin request.
It includes the `cid` of data to be pinned, as well as optional metadata in `name`, `origins`, and `meta`.
### Pin status response
![pin status response object](https://bafybeideck2fchyxna4wqwc2mo67yriokehw3yujboc5redjdaajrk2fjq.ipfs.dweb.link/pinstatus.png)
The `PinStatus` object is a representation of the current state of a pinning operation.
It includes the original `pin` object, along with the current `status` and globally unique `requestid` of the entire pinning request, which can be used for future status checks and management. Addresses in the `delegates` array are peers delegated by the pinning service for facilitating direct file transfers (more details in the provider hints section). Any additional vendor-specific information is returned in optional `info`.
## The pin lifecycle
![pinning service objects and lifecycle](https://bafybeideck2fchyxna4wqwc2mo67yriokehw3yujboc5redjdaajrk2fjq.ipfs.dweb.link/lifecycle.png)
### Creating a new pin object
The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response:
- `requestid` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, and removing the pin in the future
- `status` in `PinStatus` indicates the current state of a pin
### Checking status of in-progress pinning
`status` (in `PinStatus`) may indicate a pending state (`queued` or `pinning`). This means the data behind `Pin.cid` was not found on the pinning service and is being fetched from the IPFS network at large, which may take time.
In this case, the user can periodically check pinning progress via `GET /pins/{requestid}` until pinning is successful, or the user decides to remove the pending pin.
### Replacing an existing pin object
The user can replace an existing pin object via `POST /pins/{requestid}`. This is a shortcut for removing a pin object identified by `requestid` and creating a new one in a single API call that protects against undesired garbage collection of blocks common to both pins. Useful when updating a pin representing a huge dataset where most of blocks did not change. The new pin object `requestid` is returned in the `PinStatus` response. The old pin object is deleted automatically.
### Removing a pin object
A pin object can be removed via `DELETE /pins/{requestid}`.
## Provider hints
Pinning of new data can be accelerated by providing a list of known data sources in `Pin.origins`, and connecting at least one of them to pinning service nodes at `PinStatus.delegates`.
The most common scenario is a client putting its own IPFS node's multiaddrs in `Pin.origins`, and then directly connecting to every multiaddr returned by a pinning service in `PinStatus.delegates` to initiate transfer.
This ensures data transfer starts immediately (without waiting for provider discovery over DHT), and direct dial from a client works around peer routing issues in restrictive network topologies such as NATs.
## Custom metadata
Pinning services are encouraged to add support for additional features by leveraging the optional `Pin.meta` and `PinStatus.info` fields. While these attributes can be application- or vendor-specific, we encourage the community at large to leverage these attributes as a sandbox to come up with conventions that could become part of future revisions of this API.
### Pin metadata
String keys and values passed in `Pin.meta` are persisted with the pin object.
Potential uses:
- `Pin.meta[app_id]`: Attaching a unique identifier to pins created by an app enables filtering pins per app via `?meta={\"app_id\":<UUID>}`
- `Pin.meta[vendor_policy]`: Vendor-specific policy (for example: which region to use, how many copies to keep)
Note that it is OK for a client to omit or ignore these optional attributes; doing so should not impact the basic pinning functionality.
### Pin status info
Additional `PinStatus.info` can be returned by pinning service.
Potential uses:
- `PinStatus.info[status_details]`: more info about the current status (queue position, percentage of transferred data, summary of where data is stored, etc); when `PinStatus.status=failed`, it could provide a reason why a pin operation failed (e.g. lack of funds, DAG too big, etc.)
- `PinStatus.info[dag_size]`: the size of pinned data, along with DAG overhead
- `PinStatus.info[raw_size]`: the size of data without DAG overhead (eg. unixfs)
- `PinStatus.info[pinned_until]`: if vendor supports time-bound pins, this could indicate when the pin will expire
# Pagination and filtering
Pin objects can be listed by executing `GET /pins` with optional parameters:
- When no filters are provided, the endpoint will return a small batch of the 10 most recently created items, from the latest to the oldest.
- The number of returned items can be adjusted with the `limit` parameter (implicit default is 10).
- If the value in `PinResults.count` is bigger than the length of `PinResults.results`, the client can infer there are more results that can be queried.
- To read more items, pass the `before` filter with the timestamp from `PinStatus.created` found in the oldest item in the current batch of results. Repeat to read all results.
- Returned results can be fine-tuned by applying optional `after`, `cid`, `name`, `status`, or `meta` filters.
> **Note**: pagination by the `created` timestamp requires each value to be globally unique. Any future considerations to add support for bulk creation must account for this.
## Overview
This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [OpenAPI-spec](https://www.openapis.org/) from a remote server, you can easily generate an API client.
- API version: 0.1.1
- Package version: 1.0.0
- Build package: org.openapitools.codegen.languages.GoClientExperimentalCodegen
## Installation
Install the following dependencies:
```shell
go get github.com/stretchr/testify/assert
go get golang.org/x/oauth2
go get golang.org/x/net/context
```
Put the package under your project folder and add the following in import:
```golang
import sw "./openapi"
```
## Configuration of Server URL
Default configuration comes with `Servers` field that contains server objects as defined in the OpenAPI specification.
### Select Server Configuration
For using other server than the one defined on index 0 set context value `sw.ContextServerIndex` of type `int`.
```golang
ctx := context.WithValue(context.Background(), sw.ContextServerIndex, 1)
```
### Templated Server URL
Templated server URL is formatted using default variables from configuration or from context value `sw.ContextServerVariables` of type `map[string]string`.
```golang
ctx := context.WithValue(context.Background(), sw.ContextServerVariables, map[string]string{
"basePath": "v2",
})
```
Note, enum values are always validated and all unused variables are silently ignored.
### URLs Configuration per Operation
Each operation can use different server URL defined using `OperationServers` map in the `Configuration`.
An operation is uniquely identifield by `"{classname}Service.{nickname}"` string.
Similar rules for overriding default operation server index and variables applies by using `sw.ContextOperationServerIndices` and `sw.ContextOperationServerVariables` context maps.
```
ctx := context.WithValue(context.Background(), sw.ContextOperationServerIndices, map[string]int{
"{classname}Service.{nickname}": 2,
})
ctx = context.WithValue(context.Background(), sw.ContextOperationServerVariables, map[string]map[string]string{
"{classname}Service.{nickname}": {
"port": "8443",
},
})
```
## Documentation for API Endpoints
All URIs are relative to *https://pinning-service.example.com*
Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
*PinsApi* | [**PinsGet**](docs/PinsApi.md#pinsget) | **Get** /pins | List pin objects
*PinsApi* | [**PinsPost**](docs/PinsApi.md#pinspost) | **Post** /pins | Add pin object
*PinsApi* | [**PinsRequestidDelete**](docs/PinsApi.md#pinsrequestiddelete) | **Delete** /pins/{requestid} | Remove pin object
*PinsApi* | [**PinsRequestidGet**](docs/PinsApi.md#pinsrequestidget) | **Get** /pins/{requestid} | Get pin object
*PinsApi* | [**PinsRequestidPost**](docs/PinsApi.md#pinsrequestidpost) | **Post** /pins/{requestid} | Replace pin object
## Documentation For Models
- [Failure](docs/Failure.md)
- [FailureError](docs/FailureError.md)
- [Pin](docs/Pin.md)
- [PinResults](docs/PinResults.md)
- [PinStatus](docs/PinStatus.md)
- [Status](docs/Status.md)
## Documentation For Authorization
### accessToken
## Documentation for Utility Methods
Due to the fact that model structure members are all pointers, this package contains
a number of utility functions to easily obtain pointers to values of basic types.
Each of these functions takes a value of the given basic type and returns a pointer to it:
* `PtrBool`
* `PtrInt`
* `PtrInt32`
* `PtrInt64`
* `PtrFloat`
* `PtrFloat32`
* `PtrFloat64`
* `PtrString`
* `PtrTime`
## Author
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* IPFS Pinning Service API
*
* ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API&#x3a; - For use and implementation by pinning service providers - For use in client mode by IPFS nodes and GUI-based applications > **Note**: while ready for implementation, this spec is still a work in progress! 🏗️ **Your input and feedback are welcome and valuable as we develop this API spec. Please join the design discussion at [github.com/ipfs/pinning-services-api-spec](https://github.com/ipfs/pinning-services-api-spec).** # Schemas This section describes the most important object types and conventions. A full list of fields and schemas can be found in the `schemas` section of the [YAML file](https://github.com/ipfs/pinning-services-api-spec/blob/master/ipfs-pinning-service.yaml). ## Identifiers ### cid [Content Identifier (CID)](https://docs.ipfs.io/concepts/content-addressing/) points at the root of a DAG that is pinned recursively. ### requestid Unique identifier of a pin request. When a pin is created, the service responds with unique `requestid` that can be later used for pin removal. When the same `cid` is pinned again, a different `requestid` is returned to differentiate between those pin requests. Service implementation should use UUID, `hash(accessToken,Pin,PinStatus.created)`, or any other opaque identifier that provides equally strong protection against race conditions. ## Objects ### Pin object ![pin object](https://bafybeideck2fchyxna4wqwc2mo67yriokehw3yujboc5redjdaajrk2fjq.ipfs.dweb.link/pin.png) The `Pin` object is a representation of a pin request. It includes the `cid` of data to be pinned, as well as optional metadata in `name`, `origins`, and `meta`. ### Pin status response ![pin status response object](https://bafybeideck2fchyxna4wqwc2mo67yriokehw3yujboc5redjdaajrk2fjq.ipfs.dweb.link/pinstatus.png) The `PinStatus` object is a representation of the current state of a pinning operation. It includes the original `pin` object, along with the current `status` and globally unique `requestid` of the entire pinning request, which can be used for future status checks and management. Addresses in the `delegates` array are peers delegated by the pinning service for facilitating direct file transfers (more details in the provider hints section). Any additional vendor-specific information is returned in optional `info`. ## The pin lifecycle ![pinning service objects and lifecycle](https://bafybeideck2fchyxna4wqwc2mo67yriokehw3yujboc5redjdaajrk2fjq.ipfs.dweb.link/lifecycle.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `requestid` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, and removing the pin in the future - `status` in `PinStatus` indicates the current state of a pin ### Checking status of in-progress pinning `status` (in `PinStatus`) may indicate a pending state (`queued` or `pinning`). This means the data behind `Pin.cid` was not found on the pinning service and is being fetched from the IPFS network at large, which may take time. In this case, the user can periodically check pinning progress via `GET /pins/{requestid}` until pinning is successful, or the user decides to remove the pending pin. ### Replacing an existing pin object The user can replace an existing pin object via `POST /pins/{requestid}`. This is a shortcut for removing a pin object identified by `requestid` and creating a new one in a single API call that protects against undesired garbage collection of blocks common to both pins. Useful when updating a pin representing a huge dataset where most of blocks did not change. The new pin object `requestid` is returned in the `PinStatus` response. The old pin object is deleted automatically. ### Removing a pin object A pin object can be removed via `DELETE /pins/{requestid}`. ## Provider hints Pinning of new data can be accelerated by providing a list of known data sources in `Pin.origins`, and connecting at least one of them to pinning service nodes at `PinStatus.delegates`. The most common scenario is a client putting its own IPFS node's multiaddrs in `Pin.origins`, and then directly connecting to every multiaddr returned by a pinning service in `PinStatus.delegates` to initiate transfer. This ensures data transfer starts immediately (without waiting for provider discovery over DHT), and direct dial from a client works around peer routing issues in restrictive network topologies such as NATs. ## Custom metadata Pinning services are encouraged to add support for additional features by leveraging the optional `Pin.meta` and `PinStatus.info` fields. While these attributes can be application- or vendor-specific, we encourage the community at large to leverage these attributes as a sandbox to come up with conventions that could become part of future revisions of this API. ### Pin metadata String keys and values passed in `Pin.meta` are persisted with the pin object. Potential uses: - `Pin.meta[app_id]`: Attaching a unique identifier to pins created by an app enables filtering pins per app via `?meta={\"app_id\":<UUID>}` - `Pin.meta[vendor_policy]`: Vendor-specific policy (for example: which region to use, how many copies to keep) Note that it is OK for a client to omit or ignore these optional attributes; doing so should not impact the basic pinning functionality. ### Pin status info Additional `PinStatus.info` can be returned by pinning service. Potential uses: - `PinStatus.info[status_details]`: more info about the current status (queue position, percentage of transferred data, summary of where data is stored, etc); when `PinStatus.status=failed`, it could provide a reason why a pin operation failed (e.g. lack of funds, DAG too big, etc.) - `PinStatus.info[dag_size]`: the size of pinned data, along with DAG overhead - `PinStatus.info[raw_size]`: the size of data without DAG overhead (eg. unixfs) - `PinStatus.info[pinned_until]`: if vendor supports time-bound pins, this could indicate when the pin will expire # Pagination and filtering Pin objects can be listed by executing `GET /pins` with optional parameters: - When no filters are provided, the endpoint will return a small batch of the 10 most recently created items, from the latest to the oldest. - The number of returned items can be adjusted with the `limit` parameter (implicit default is 10). - If the value in `PinResults.count` is bigger than the length of `PinResults.results`, the client can infer there are more results that can be queried. - To read more items, pass the `before` filter with the timestamp from `PinStatus.created` found in the oldest item in the current batch of results. Repeat to read all results. - Returned results can be fine-tuned by applying optional `after`, `cid`, `name`, `status`, or `meta` filters. > **Note**: pagination by the `created` timestamp requires each value to be globally unique. Any future considerations to add support for bulk creation must account for this.
*
* API version: 0.1.1
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"context"
"fmt"
"net/http"
"strings"
)
// contextKeys are used to identify the type of value in the context.
// Since these are string, it is possible to get a short description of the
// context key for logging and debugging using key.String().
type contextKey string
func (c contextKey) String() string {
return "auth " + string(c)
}
var (
// ContextOAuth2 takes an oauth2.TokenSource as authentication for the request.
ContextOAuth2 = contextKey("token")
// ContextBasicAuth takes BasicAuth as authentication for the request.
ContextBasicAuth = contextKey("basic")
// ContextAccessToken takes a string oauth2 access token as authentication for the request.
ContextAccessToken = contextKey("accesstoken")
// ContextAPIKeys takes a string apikey as authentication for the request
ContextAPIKeys = contextKey("apiKeys")
// ContextHttpSignatureAuth takes HttpSignatureAuth as authentication for the request.
ContextHttpSignatureAuth = contextKey("httpsignature")
// ContextServerIndex uses a server configuration from the index.
ContextServerIndex = contextKey("serverIndex")
// ContextOperationServerIndices uses a server configuration from the index mapping.
ContextOperationServerIndices = contextKey("serverOperationIndices")
// ContextServerVariables overrides a server configuration variables.
ContextServerVariables = contextKey("serverVariables")
// ContextOperationServerVariables overrides a server configuration variables using operation specific values.
ContextOperationServerVariables = contextKey("serverOperationVariables")
)
// BasicAuth provides basic http authentication to a request passed via context using ContextBasicAuth
type BasicAuth struct {
UserName string `json:"userName,omitempty"`
Password string `json:"password,omitempty"`
}
// APIKey provides API key based authentication to a request passed via context using ContextAPIKey
type APIKey struct {
Key string
Prefix string
}
// ServerVariable stores the information about a server variable
type ServerVariable struct {
Description string
DefaultValue string
EnumValues []string
}
// ServerConfiguration stores the information about a server
type ServerConfiguration struct {
URL string
Description string
Variables map[string]ServerVariable
}
// ServerConfigurations stores multiple ServerConfiguration items
type ServerConfigurations []ServerConfiguration
// Configuration stores the configuration of the API client
type Configuration struct {
Host string `json:"host,omitempty"`
Scheme string `json:"scheme,omitempty"`
DefaultHeader map[string]string `json:"defaultHeader,omitempty"`
UserAgent string `json:"userAgent,omitempty"`
Debug bool `json:"debug,omitempty"`
Servers ServerConfigurations
OperationServers map[string]ServerConfigurations
HTTPClient *http.Client
}
// NewConfiguration returns a new Configuration object
func NewConfiguration() *Configuration {
cfg := &Configuration{
DefaultHeader: make(map[string]string),
UserAgent: "OpenAPI-Generator/1.0.0/go",
Debug: false,
Servers: ServerConfigurations{
{
URL: "https://pinning-service.example.com",
Description: "No description provided",
},
},
OperationServers: map[string]ServerConfigurations{},
}
return cfg
}
// AddDefaultHeader adds a new HTTP header to the default header in the request
func (c *Configuration) AddDefaultHeader(key string, value string) {
c.DefaultHeader[key] = value
}
// URL formats template on a index using given variables
func (sc ServerConfigurations) URL(index int, variables map[string]string) (string, error) {
if index < 0 || len(sc) <= index {
return "", fmt.Errorf("Index %v out of range %v", index, len(sc)-1)
}
server := sc[index]
url := server.URL
// go through variables and replace placeholders
for name, variable := range server.Variables {
if value, ok := variables[name]; ok {
found := bool(len(variable.EnumValues) == 0)
for _, enumValue := range variable.EnumValues {
if value == enumValue {
found = true
}
}
if !found {
return "", fmt.Errorf("The variable %s in the server URL has invalid value %v. Must be %v", name, value, variable.EnumValues)
}
url = strings.Replace(url, "{"+name+"}", value, -1)
} else {
url = strings.Replace(url, "{"+name+"}", variable.DefaultValue, -1)
}
}
return url, nil
}
// ServerURL returns URL based on server settings
func (c *Configuration) ServerURL(index int, variables map[string]string) (string, error) {
return c.Servers.URL(index, variables)
}
func getServerIndex(ctx context.Context) (int, error) {
si := ctx.Value(ContextServerIndex)
if si != nil {
if index, ok := si.(int); ok {
return index, nil
}
return 0, reportError("Invalid type %T should be int", si)
}
return 0, nil
}
func getServerOperationIndex(ctx context.Context, endpoint string) (int, error) {
osi := ctx.Value(ContextOperationServerIndices)
if osi != nil {
if operationIndices, ok := osi.(map[string]int); !ok {
return 0, reportError("Invalid type %T should be map[string]int", osi)
} else {
index, ok := operationIndices[endpoint]
if ok {
return index, nil
}
}
}
return getServerIndex(ctx)
}
func getServerVariables(ctx context.Context) (map[string]string, error) {
sv := ctx.Value(ContextServerVariables)
if sv != nil {
if variables, ok := sv.(map[string]string); ok {
return variables, nil
}
return nil, reportError("ctx value of ContextServerVariables has invalid type %T should be map[string]string", sv)
}
return nil, nil
}
func getServerOperationVariables(ctx context.Context, endpoint string) (map[string]string, error) {
osv := ctx.Value(ContextOperationServerVariables)
if osv != nil {
if operationVariables, ok := osv.(map[string]map[string]string); !ok {
return nil, reportError("ctx value of ContextOperationServerVariables has invalid type %T should be map[string]map[string]string", osv)
} else {
variables, ok := operationVariables[endpoint]
if ok {
return variables, nil
}
}
}
return getServerVariables(ctx)
}
// ServerURLWithContext returns a new server URL given an endpoint
func (c *Configuration) ServerURLWithContext(ctx context.Context, endpoint string) (string, error) {
sc, ok := c.OperationServers[endpoint]
if !ok {
sc = c.Servers
}
if ctx == nil {
return sc.URL(0, nil)
}
index, err := getServerOperationIndex(ctx, endpoint)
if err != nil {
return "", err
}
variables, err := getServerOperationVariables(ctx, endpoint)
if err != nil {
return "", err
}
return sc.URL(index, variables)
}
# Failure
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**Error** | [**FailureError**](Failure_error.md) | |
## Methods
### NewFailure
`func NewFailure(error_ FailureError, ) *Failure`
NewFailure instantiates a new Failure object
This constructor will assign default values to properties that have it defined,
and makes sure properties required by API are set, but the set of arguments
will change when the set of required properties is changed
### NewFailureWithDefaults
`func NewFailureWithDefaults() *Failure`
NewFailureWithDefaults instantiates a new Failure object
This constructor will only assign default values to properties that have it defined,
but it doesn't guarantee that properties required by API are set
### GetError
`func (o *Failure) GetError() FailureError`
GetError returns the Error field if non-nil, zero value otherwise.
### GetErrorOk
`func (o *Failure) GetErrorOk() (*FailureError, bool)`
GetErrorOk returns a tuple with the Error field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.
### SetError
`func (o *Failure) SetError(v FailureError)`
SetError sets Error field to given value.
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
# FailureError
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**Reason** | **string** | Mandatory string identifying the type of error |
**Details** | Pointer to **string** | Optional, longer description of the error; may include UUID of transaction for support, links to documentation etc | [optional]
## Methods
### NewFailureError
`func NewFailureError(reason string, ) *FailureError`
NewFailureError instantiates a new FailureError object
This constructor will assign default values to properties that have it defined,
and makes sure properties required by API are set, but the set of arguments
will change when the set of required properties is changed
### NewFailureErrorWithDefaults
`func NewFailureErrorWithDefaults() *FailureError`
NewFailureErrorWithDefaults instantiates a new FailureError object
This constructor will only assign default values to properties that have it defined,
but it doesn't guarantee that properties required by API are set
### GetReason
`func (o *FailureError) GetReason() string`
GetReason returns the Reason field if non-nil, zero value otherwise.
### GetReasonOk
`func (o *FailureError) GetReasonOk() (*string, bool)`
GetReasonOk returns a tuple with the Reason field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.
### SetReason
`func (o *FailureError) SetReason(v string)`
SetReason sets Reason field to given value.
### GetDetails
`func (o *FailureError) GetDetails() string`
GetDetails returns the Details field if non-nil, zero value otherwise.
### GetDetailsOk
`func (o *FailureError) GetDetailsOk() (*string, bool)`
GetDetailsOk returns a tuple with the Details field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.
### SetDetails
`func (o *FailureError) SetDetails(v string)`
SetDetails sets Details field to given value.
### HasDetails
`func (o *FailureError) HasDetails() bool`
HasDetails returns a boolean if a field has been set.
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
# Pin
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**Cid** | **string** | Content Identifier (CID) to be pinned recursively |
**Name** | Pointer to **string** | Optional name for pinned data; can be used for lookups later | [optional]
**Origins** | Pointer to **[]string** | Optional list of multiaddrs known to provide the data | [optional]
**Meta** | Pointer to **map[string]string** | Optional metadata for pin object | [optional]
## Methods
### NewPin
`func NewPin(cid string, ) *Pin`
NewPin instantiates a new Pin object
This constructor will assign default values to properties that have it defined,
and makes sure properties required by API are set, but the set of arguments
will change when the set of required properties is changed
### NewPinWithDefaults
`func NewPinWithDefaults() *Pin`
NewPinWithDefaults instantiates a new Pin object
This constructor will only assign default values to properties that have it defined,
but it doesn't guarantee that properties required by API are set
### GetCid
`func (o *Pin) GetCid() string`
GetCid returns the Cid field if non-nil, zero value otherwise.
### GetCidOk
`func (o *Pin) GetCidOk() (*string, bool)`
GetCidOk returns a tuple with the Cid field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.
### SetCid
`func (o *Pin) SetCid(v string)`
SetCid sets Cid field to given value.
### GetName
`func (o *Pin) GetName() string`
GetName returns the Name field if non-nil, zero value otherwise.
### GetNameOk
`func (o *Pin) GetNameOk() (*string, bool)`
GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.
### SetName
`func (o *Pin) SetName(v string)`
SetName sets Name field to given value.
### HasName
`func (o *Pin) HasName() bool`
HasName returns a boolean if a field has been set.
### GetOrigins
`func (o *Pin) GetOrigins() []string`
GetOrigins returns the Origins field if non-nil, zero value otherwise.
### GetOriginsOk
`func (o *Pin) GetOriginsOk() (*[]string, bool)`
GetOriginsOk returns a tuple with the Origins field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.
### SetOrigins
`func (o *Pin) SetOrigins(v []string)`
SetOrigins sets Origins field to given value.
### HasOrigins
`func (o *Pin) HasOrigins() bool`
HasOrigins returns a boolean if a field has been set.
### GetMeta
`func (o *Pin) GetMeta() map[string]string`
GetMeta returns the Meta field if non-nil, zero value otherwise.
### GetMetaOk
`func (o *Pin) GetMetaOk() (*map[string]string, bool)`
GetMetaOk returns a tuple with the Meta field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.
### SetMeta
`func (o *Pin) SetMeta(v map[string]string)`
SetMeta sets Meta field to given value.
### HasMeta
`func (o *Pin) HasMeta() bool`
HasMeta returns a boolean if a field has been set.
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
# PinResults
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**Count** | **int32** | The total number of pin objects that exist for passed query filters |
**Results** | [**[]PinStatus**](PinStatus.md) | An array of PinStatus results |
## Methods
### NewPinResults
`func NewPinResults(count int32, results []PinStatus, ) *PinResults`
NewPinResults instantiates a new PinResults object
This constructor will assign default values to properties that have it defined,
and makes sure properties required by API are set, but the set of arguments
will change when the set of required properties is changed
### NewPinResultsWithDefaults
`func NewPinResultsWithDefaults() *PinResults`
NewPinResultsWithDefaults instantiates a new PinResults object
This constructor will only assign default values to properties that have it defined,
but it doesn't guarantee that properties required by API are set
### GetCount
`func (o *PinResults) GetCount() int32`
GetCount returns the Count field if non-nil, zero value otherwise.
### GetCountOk
`func (o *PinResults) GetCountOk() (*int32, bool)`
GetCountOk returns a tuple with the Count field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.
### SetCount
`func (o *PinResults) SetCount(v int32)`
SetCount sets Count field to given value.
### GetResults
`func (o *PinResults) GetResults() []PinStatus`
GetResults returns the Results field if non-nil, zero value otherwise.
### GetResultsOk
`func (o *PinResults) GetResultsOk() (*[]PinStatus, bool)`
GetResultsOk returns a tuple with the Results field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.
### SetResults
`func (o *PinResults) SetResults(v []PinStatus)`
SetResults sets Results field to given value.
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
# PinStatus
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**Requestid** | **string** | Globally unique identifier of the pin request; can be used to check the status of ongoing pinning, or pin removal |
**Status** | [**Status**](Status.md) | |
**Created** | [**time.Time**](time.Time.md) | Immutable timestamp indicating when a pin request entered a pinning service; can be used for filtering results and pagination |
**Pin** | [**Pin**](Pin.md) | |
**Delegates** | **[]string** | List of multiaddrs designated by pinning service for transferring any new data from external peers |
**Info** | Pointer to **map[string]string** | Optional info for PinStatus response | [optional]
## Methods
### NewPinStatus
`func NewPinStatus(requestid string, status Status, created time.Time, pin Pin, delegates []string, ) *PinStatus`
NewPinStatus instantiates a new PinStatus object
This constructor will assign default values to properties that have it defined,
and makes sure properties required by API are set, but the set of arguments
will change when the set of required properties is changed
### NewPinStatusWithDefaults
`func NewPinStatusWithDefaults() *PinStatus`
NewPinStatusWithDefaults instantiates a new PinStatus object
This constructor will only assign default values to properties that have it defined,
but it doesn't guarantee that properties required by API are set
### GetRequestid
`func (o *PinStatus) GetRequestid() string`
GetRequestid returns the Requestid field if non-nil, zero value otherwise.
### GetRequestidOk
`func (o *PinStatus) GetRequestidOk() (*string, bool)`
GetRequestidOk returns a tuple with the Requestid field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.
### SetRequestid
`func (o *PinStatus) SetRequestid(v string)`
SetRequestid sets Requestid field to given value.
### GetStatus
`func (o *PinStatus) GetStatus() Status`
GetStatus returns the Status field if non-nil, zero value otherwise.
### GetStatusOk
`func (o *PinStatus) GetStatusOk() (*Status, bool)`
GetStatusOk returns a tuple with the Status field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.
### SetStatus
`func (o *PinStatus) SetStatus(v Status)`
SetStatus sets Status field to given value.
### GetCreated
`func (o *PinStatus) GetCreated() time.Time`
GetCreated returns the Created field if non-nil, zero value otherwise.
### GetCreatedOk
`func (o *PinStatus) GetCreatedOk() (*time.Time, bool)`
GetCreatedOk returns a tuple with the Created field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.
### SetCreated
`func (o *PinStatus) SetCreated(v time.Time)`
SetCreated sets Created field to given value.
### GetPin
`func (o *PinStatus) GetPin() Pin`
GetPin returns the Pin field if non-nil, zero value otherwise.
### GetPinOk
`func (o *PinStatus) GetPinOk() (*Pin, bool)`
GetPinOk returns a tuple with the Pin field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.
### SetPin
`func (o *PinStatus) SetPin(v Pin)`
SetPin sets Pin field to given value.
### GetDelegates
`func (o *PinStatus) GetDelegates() []string`
GetDelegates returns the Delegates field if non-nil, zero value otherwise.
### GetDelegatesOk
`func (o *PinStatus) GetDelegatesOk() (*[]string, bool)`
GetDelegatesOk returns a tuple with the Delegates field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.
### SetDelegates
`func (o *PinStatus) SetDelegates(v []string)`
SetDelegates sets Delegates field to given value.
### GetInfo
`func (o *PinStatus) GetInfo() map[string]string`
GetInfo returns the Info field if non-nil, zero value otherwise.
### GetInfoOk
`func (o *PinStatus) GetInfoOk() (*map[string]string, bool)`
GetInfoOk returns a tuple with the Info field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.
### SetInfo
`func (o *PinStatus) SetInfo(v map[string]string)`
SetInfo sets Info field to given value.
### HasInfo
`func (o *PinStatus) HasInfo() bool`
HasInfo returns a boolean if a field has been set.
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
# \PinsApi
All URIs are relative to *https://pinning-service.example.com*
Method | HTTP request | Description
------------- | ------------- | -------------
[**PinsGet**](PinsApi.md#PinsGet) | **Get** /pins | List pin objects
[**PinsPost**](PinsApi.md#PinsPost) | **Post** /pins | Add pin object
[**PinsRequestidDelete**](PinsApi.md#PinsRequestidDelete) | **Delete** /pins/{requestid} | Remove pin object
[**PinsRequestidGet**](PinsApi.md#PinsRequestidGet) | **Get** /pins/{requestid} | Get pin object
[**PinsRequestidPost**](PinsApi.md#PinsRequestidPost) | **Post** /pins/{requestid} | Replace pin object
## PinsGet
> PinResults PinsGet(ctx).Cid(cid).Name(name).Status(status).Before(before).After(after).Limit(limit).Meta(meta).Execute()
List pin objects
### Example
```go
package main
import (
"context"
"fmt"
"os"
openapiclient "./openapi"
)
func main() {
cid := []string{"Inner_example"} // []string | Return pin objects responsible for pinning the specified CID(s); be aware that using longer hash functions introduces further constraints on the number of CIDs that will fit under the limit of 2000 characters per URL in browser contexts (optional)
name := "name_example" // string | Return pin objects with names that contain provided value (case-insensitive, partial or full match) (optional)
status := []Status{openapiclient.Status{}} // []Status | Return pin objects for pins with the specified status (optional)
before := Get-Date // time.Time | Return results created (queued) before provided timestamp (optional)
after := Get-Date // time.Time | Return results created (queued) after provided timestamp (optional)
limit := 987 // int32 | Max records to return (optional) (default to 10)
meta := map[string]string{ "Key" = "Value" } // map[string]string | Return pin objects that match specified metadata (optional)
configuration := openapiclient.NewConfiguration()
api_client := openapiclient.NewAPIClient(configuration)
resp, r, err := api_client.PinsApi.PinsGet(context.Background(), ).Cid(cid).Name(name).Status(status).Before(before).After(after).Limit(limit).Meta(meta).Execute()
if err != nil {
fmt.Fprintf(os.Stderr, "Error when calling `PinsApi.PinsGet``: %v\n", err)
fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r)
}
// response from `PinsGet`: PinResults
fmt.Fprintf(os.Stdout, "Response from `PinsApi.PinsGet`: %v\n", resp)
}
```
### Path Parameters
### Other Parameters
Other parameters are passed through a pointer to a apiPinsGetRequest struct via the builder pattern
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**cid** | [**[]string**](string.md) | Return pin objects responsible for pinning the specified CID(s); be aware that using longer hash functions introduces further constraints on the number of CIDs that will fit under the limit of 2000 characters per URL in browser contexts |
**name** | **string** | Return pin objects with names that contain provided value (case-insensitive, partial or full match) |
**status** | [**[]Status**](Status.md) | Return pin objects for pins with the specified status |
**before** | **time.Time** | Return results created (queued) before provided timestamp |
**after** | **time.Time** | Return results created (queued) after provided timestamp |
**limit** | **int32** | Max records to return | [default to 10]
**meta** | [**map[string]string**](string.md) | Return pin objects that match specified metadata |
### Return type
[**PinResults**](PinResults.md)
### Authorization
[accessToken](../README.md#accessToken)
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints)
[[Back to Model list]](../README.md#documentation-for-models)
[[Back to README]](../README.md)
## PinsPost
> PinStatus PinsPost(ctx).Pin(pin).Execute()
Add pin object
### Example
```go
package main
import (
"context"
"fmt"
"os"
openapiclient "./openapi"
)
func main() {
pin := openapiclient.Pin{Cid: "Cid_example", Name: "Name_example", Origins: []string{"Origins_example"), Meta: map[string]string{ "Key" = "Value" }} // Pin |
configuration := openapiclient.NewConfiguration()
api_client := openapiclient.NewAPIClient(configuration)
resp, r, err := api_client.PinsApi.PinsPost(context.Background(), pin).Execute()
if err != nil {
fmt.Fprintf(os.Stderr, "Error when calling `PinsApi.PinsPost``: %v\n", err)
fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r)
}
// response from `PinsPost`: PinStatus
fmt.Fprintf(os.Stdout, "Response from `PinsApi.PinsPost`: %v\n", resp)
}
```
### Path Parameters
### Other Parameters
Other parameters are passed through a pointer to a apiPinsPostRequest struct via the builder pattern
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**pin** | [**Pin**](Pin.md) | |
### Return type
[**PinStatus**](PinStatus.md)
### Authorization
[accessToken](../README.md#accessToken)
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints)
[[Back to Model list]](../README.md#documentation-for-models)
[[Back to README]](../README.md)
## PinsRequestidDelete
> PinsRequestidDelete(ctx, requestid).Execute()
Remove pin object
### Example
```go
package main
import (
"context"
"fmt"
"os"
openapiclient "./openapi"
)
func main() {
requestid := "requestid_example" // string |
configuration := openapiclient.NewConfiguration()
api_client := openapiclient.NewAPIClient(configuration)
resp, r, err := api_client.PinsApi.PinsRequestidDelete(context.Background(), requestid).Execute()
if err != nil {
fmt.Fprintf(os.Stderr, "Error when calling `PinsApi.PinsRequestidDelete``: %v\n", err)
fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r)
}
}
```
### Path Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc.
**requestid** | **string** | |
### Other Parameters
Other parameters are passed through a pointer to a apiPinsRequestidDeleteRequest struct via the builder pattern
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
### Return type
(empty response body)
### Authorization
[accessToken](../README.md#accessToken)
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints)
[[Back to Model list]](../README.md#documentation-for-models)
[[Back to README]](../README.md)
## PinsRequestidGet
> PinStatus PinsRequestidGet(ctx, requestid).Execute()
Get pin object
### Example
```go
package main
import (
"context"
"fmt"
"os"
openapiclient "./openapi"
)
func main() {
requestid := "requestid_example" // string |
configuration := openapiclient.NewConfiguration()
api_client := openapiclient.NewAPIClient(configuration)
resp, r, err := api_client.PinsApi.PinsRequestidGet(context.Background(), requestid).Execute()
if err != nil {
fmt.Fprintf(os.Stderr, "Error when calling `PinsApi.PinsRequestidGet``: %v\n", err)
fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r)
}
// response from `PinsRequestidGet`: PinStatus
fmt.Fprintf(os.Stdout, "Response from `PinsApi.PinsRequestidGet`: %v\n", resp)
}
```
### Path Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc.
**requestid** | **string** | |
### Other Parameters
Other parameters are passed through a pointer to a apiPinsRequestidGetRequest struct via the builder pattern
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
### Return type
[**PinStatus**](PinStatus.md)
### Authorization
[accessToken](../README.md#accessToken)
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints)
[[Back to Model list]](../README.md#documentation-for-models)
[[Back to README]](../README.md)
## PinsRequestidPost
> PinStatus PinsRequestidPost(ctx, requestid).Pin(pin).Execute()
Replace pin object
### Example
```go
package main
import (
"context"
"fmt"
"os"
openapiclient "./openapi"
)
func main() {
requestid := "requestid_example" // string |
pin := openapiclient.Pin{Cid: "Cid_example", Name: "Name_example", Origins: []string{"Origins_example"), Meta: map[string]string{ "Key" = "Value" }} // Pin |
configuration := openapiclient.NewConfiguration()
api_client := openapiclient.NewAPIClient(configuration)
resp, r, err := api_client.PinsApi.PinsRequestidPost(context.Background(), requestid, pin).Execute()
if err != nil {
fmt.Fprintf(os.Stderr, "Error when calling `PinsApi.PinsRequestidPost``: %v\n", err)
fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r)
}
// response from `PinsRequestidPost`: PinStatus
fmt.Fprintf(os.Stdout, "Response from `PinsApi.PinsRequestidPost`: %v\n", resp)
}
```
### Path Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc.
**requestid** | **string** | |
### Other Parameters
Other parameters are passed through a pointer to a apiPinsRequestidPostRequest struct via the builder pattern
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**pin** | [**Pin**](Pin.md) | |
### Return type
[**PinStatus**](PinStatus.md)
### Authorization
[accessToken](../README.md#accessToken)
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints)
[[Back to Model list]](../README.md#documentation-for-models)
[[Back to README]](../README.md)
# Status
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
/*
* IPFS Pinning Service API
*
* ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API&#x3a; - For use and implementation by pinning service providers - For use in client mode by IPFS nodes and GUI-based applications > **Note**: while ready for implementation, this spec is still a work in progress! 🏗️ **Your input and feedback are welcome and valuable as we develop this API spec. Please join the design discussion at [github.com/ipfs/pinning-services-api-spec](https://github.com/ipfs/pinning-services-api-spec).** # Schemas This section describes the most important object types and conventions. A full list of fields and schemas can be found in the `schemas` section of the [YAML file](https://github.com/ipfs/pinning-services-api-spec/blob/master/ipfs-pinning-service.yaml). ## Identifiers ### cid [Content Identifier (CID)](https://docs.ipfs.io/concepts/content-addressing/) points at the root of a DAG that is pinned recursively. ### requestid Unique identifier of a pin request. When a pin is created, the service responds with unique `requestid` that can be later used for pin removal. When the same `cid` is pinned again, a different `requestid` is returned to differentiate between those pin requests. Service implementation should use UUID, `hash(accessToken,Pin,PinStatus.created)`, or any other opaque identifier that provides equally strong protection against race conditions. ## Objects ### Pin object ![pin object](https://bafybeideck2fchyxna4wqwc2mo67yriokehw3yujboc5redjdaajrk2fjq.ipfs.dweb.link/pin.png) The `Pin` object is a representation of a pin request. It includes the `cid` of data to be pinned, as well as optional metadata in `name`, `origins`, and `meta`. ### Pin status response ![pin status response object](https://bafybeideck2fchyxna4wqwc2mo67yriokehw3yujboc5redjdaajrk2fjq.ipfs.dweb.link/pinstatus.png) The `PinStatus` object is a representation of the current state of a pinning operation. It includes the original `pin` object, along with the current `status` and globally unique `requestid` of the entire pinning request, which can be used for future status checks and management. Addresses in the `delegates` array are peers delegated by the pinning service for facilitating direct file transfers (more details in the provider hints section). Any additional vendor-specific information is returned in optional `info`. ## The pin lifecycle ![pinning service objects and lifecycle](https://bafybeideck2fchyxna4wqwc2mo67yriokehw3yujboc5redjdaajrk2fjq.ipfs.dweb.link/lifecycle.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `requestid` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, and removing the pin in the future - `status` in `PinStatus` indicates the current state of a pin ### Checking status of in-progress pinning `status` (in `PinStatus`) may indicate a pending state (`queued` or `pinning`). This means the data behind `Pin.cid` was not found on the pinning service and is being fetched from the IPFS network at large, which may take time. In this case, the user can periodically check pinning progress via `GET /pins/{requestid}` until pinning is successful, or the user decides to remove the pending pin. ### Replacing an existing pin object The user can replace an existing pin object via `POST /pins/{requestid}`. This is a shortcut for removing a pin object identified by `requestid` and creating a new one in a single API call that protects against undesired garbage collection of blocks common to both pins. Useful when updating a pin representing a huge dataset where most of blocks did not change. The new pin object `requestid` is returned in the `PinStatus` response. The old pin object is deleted automatically. ### Removing a pin object A pin object can be removed via `DELETE /pins/{requestid}`. ## Provider hints Pinning of new data can be accelerated by providing a list of known data sources in `Pin.origins`, and connecting at least one of them to pinning service nodes at `PinStatus.delegates`. The most common scenario is a client putting its own IPFS node's multiaddrs in `Pin.origins`, and then directly connecting to every multiaddr returned by a pinning service in `PinStatus.delegates` to initiate transfer. This ensures data transfer starts immediately (without waiting for provider discovery over DHT), and direct dial from a client works around peer routing issues in restrictive network topologies such as NATs. ## Custom metadata Pinning services are encouraged to add support for additional features by leveraging the optional `Pin.meta` and `PinStatus.info` fields. While these attributes can be application- or vendor-specific, we encourage the community at large to leverage these attributes as a sandbox to come up with conventions that could become part of future revisions of this API. ### Pin metadata String keys and values passed in `Pin.meta` are persisted with the pin object. Potential uses: - `Pin.meta[app_id]`: Attaching a unique identifier to pins created by an app enables filtering pins per app via `?meta={\"app_id\":<UUID>}` - `Pin.meta[vendor_policy]`: Vendor-specific policy (for example: which region to use, how many copies to keep) Note that it is OK for a client to omit or ignore these optional attributes; doing so should not impact the basic pinning functionality. ### Pin status info Additional `PinStatus.info` can be returned by pinning service. Potential uses: - `PinStatus.info[status_details]`: more info about the current status (queue position, percentage of transferred data, summary of where data is stored, etc); when `PinStatus.status=failed`, it could provide a reason why a pin operation failed (e.g. lack of funds, DAG too big, etc.) - `PinStatus.info[dag_size]`: the size of pinned data, along with DAG overhead - `PinStatus.info[raw_size]`: the size of data without DAG overhead (eg. unixfs) - `PinStatus.info[pinned_until]`: if vendor supports time-bound pins, this could indicate when the pin will expire # Pagination and filtering Pin objects can be listed by executing `GET /pins` with optional parameters: - When no filters are provided, the endpoint will return a small batch of the 10 most recently created items, from the latest to the oldest. - The number of returned items can be adjusted with the `limit` parameter (implicit default is 10). - If the value in `PinResults.count` is bigger than the length of `PinResults.results`, the client can infer there are more results that can be queried. - To read more items, pass the `before` filter with the timestamp from `PinStatus.created` found in the oldest item in the current batch of results. Repeat to read all results. - Returned results can be fine-tuned by applying optional `after`, `cid`, `name`, `status`, or `meta` filters. > **Note**: pagination by the `created` timestamp requires each value to be globally unique. Any future considerations to add support for bulk creation must account for this.
*
* API version: 0.1.1
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"encoding/json"
)
// Failure Response for a failed request
type Failure struct {
Error FailureError `json:"error"`
}
// NewFailure instantiates a new Failure object
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed
func NewFailure(error_ FailureError) *Failure {
this := Failure{}
this.Error = error_
return &this
}
// NewFailureWithDefaults instantiates a new Failure object
// This constructor will only assign default values to properties that have it defined,
// but it doesn't guarantee that properties required by API are set
func NewFailureWithDefaults() *Failure {
this := Failure{}
return &this
}
// GetError returns the Error field value
func (o *Failure) GetError() FailureError {
if o == nil {
var ret FailureError
return ret
}
return o.Error
}
// GetErrorOk returns a tuple with the Error field value
// and a boolean to check if the value has been set.
func (o *Failure) GetErrorOk() (*FailureError, bool) {
if o == nil {
return nil, false
}
return &o.Error, true
}
// SetError sets field value
func (o *Failure) SetError(v FailureError) {
o.Error = v
}
func (o Failure) MarshalJSON() ([]byte, error) {
toSerialize := map[string]interface{}{}
if true {
toSerialize["error"] = o.Error
}
return json.Marshal(toSerialize)
}
type NullableFailure struct {
value *Failure
isSet bool
}
func (v NullableFailure) Get() *Failure {
return v.value
}
func (v *NullableFailure) Set(val *Failure) {
v.value = val
v.isSet = true
}
func (v NullableFailure) IsSet() bool {
return v.isSet
}
func (v *NullableFailure) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableFailure(val *Failure) *NullableFailure {
return &NullableFailure{value: val, isSet: true}
}
func (v NullableFailure) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableFailure) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}
/*
* IPFS Pinning Service API
*
* ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API&#x3a; - For use and implementation by pinning service providers - For use in client mode by IPFS nodes and GUI-based applications > **Note**: while ready for implementation, this spec is still a work in progress! 🏗️ **Your input and feedback are welcome and valuable as we develop this API spec. Please join the design discussion at [github.com/ipfs/pinning-services-api-spec](https://github.com/ipfs/pinning-services-api-spec).** # Schemas This section describes the most important object types and conventions. A full list of fields and schemas can be found in the `schemas` section of the [YAML file](https://github.com/ipfs/pinning-services-api-spec/blob/master/ipfs-pinning-service.yaml). ## Identifiers ### cid [Content Identifier (CID)](https://docs.ipfs.io/concepts/content-addressing/) points at the root of a DAG that is pinned recursively. ### requestid Unique identifier of a pin request. When a pin is created, the service responds with unique `requestid` that can be later used for pin removal. When the same `cid` is pinned again, a different `requestid` is returned to differentiate between those pin requests. Service implementation should use UUID, `hash(accessToken,Pin,PinStatus.created)`, or any other opaque identifier that provides equally strong protection against race conditions. ## Objects ### Pin object ![pin object](https://bafybeideck2fchyxna4wqwc2mo67yriokehw3yujboc5redjdaajrk2fjq.ipfs.dweb.link/pin.png) The `Pin` object is a representation of a pin request. It includes the `cid` of data to be pinned, as well as optional metadata in `name`, `origins`, and `meta`. ### Pin status response ![pin status response object](https://bafybeideck2fchyxna4wqwc2mo67yriokehw3yujboc5redjdaajrk2fjq.ipfs.dweb.link/pinstatus.png) The `PinStatus` object is a representation of the current state of a pinning operation. It includes the original `pin` object, along with the current `status` and globally unique `requestid` of the entire pinning request, which can be used for future status checks and management. Addresses in the `delegates` array are peers delegated by the pinning service for facilitating direct file transfers (more details in the provider hints section). Any additional vendor-specific information is returned in optional `info`. ## The pin lifecycle ![pinning service objects and lifecycle](https://bafybeideck2fchyxna4wqwc2mo67yriokehw3yujboc5redjdaajrk2fjq.ipfs.dweb.link/lifecycle.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `requestid` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, and removing the pin in the future - `status` in `PinStatus` indicates the current state of a pin ### Checking status of in-progress pinning `status` (in `PinStatus`) may indicate a pending state (`queued` or `pinning`). This means the data behind `Pin.cid` was not found on the pinning service and is being fetched from the IPFS network at large, which may take time. In this case, the user can periodically check pinning progress via `GET /pins/{requestid}` until pinning is successful, or the user decides to remove the pending pin. ### Replacing an existing pin object The user can replace an existing pin object via `POST /pins/{requestid}`. This is a shortcut for removing a pin object identified by `requestid` and creating a new one in a single API call that protects against undesired garbage collection of blocks common to both pins. Useful when updating a pin representing a huge dataset where most of blocks did not change. The new pin object `requestid` is returned in the `PinStatus` response. The old pin object is deleted automatically. ### Removing a pin object A pin object can be removed via `DELETE /pins/{requestid}`. ## Provider hints Pinning of new data can be accelerated by providing a list of known data sources in `Pin.origins`, and connecting at least one of them to pinning service nodes at `PinStatus.delegates`. The most common scenario is a client putting its own IPFS node's multiaddrs in `Pin.origins`, and then directly connecting to every multiaddr returned by a pinning service in `PinStatus.delegates` to initiate transfer. This ensures data transfer starts immediately (without waiting for provider discovery over DHT), and direct dial from a client works around peer routing issues in restrictive network topologies such as NATs. ## Custom metadata Pinning services are encouraged to add support for additional features by leveraging the optional `Pin.meta` and `PinStatus.info` fields. While these attributes can be application- or vendor-specific, we encourage the community at large to leverage these attributes as a sandbox to come up with conventions that could become part of future revisions of this API. ### Pin metadata String keys and values passed in `Pin.meta` are persisted with the pin object. Potential uses: - `Pin.meta[app_id]`: Attaching a unique identifier to pins created by an app enables filtering pins per app via `?meta={\"app_id\":<UUID>}` - `Pin.meta[vendor_policy]`: Vendor-specific policy (for example: which region to use, how many copies to keep) Note that it is OK for a client to omit or ignore these optional attributes; doing so should not impact the basic pinning functionality. ### Pin status info Additional `PinStatus.info` can be returned by pinning service. Potential uses: - `PinStatus.info[status_details]`: more info about the current status (queue position, percentage of transferred data, summary of where data is stored, etc); when `PinStatus.status=failed`, it could provide a reason why a pin operation failed (e.g. lack of funds, DAG too big, etc.) - `PinStatus.info[dag_size]`: the size of pinned data, along with DAG overhead - `PinStatus.info[raw_size]`: the size of data without DAG overhead (eg. unixfs) - `PinStatus.info[pinned_until]`: if vendor supports time-bound pins, this could indicate when the pin will expire # Pagination and filtering Pin objects can be listed by executing `GET /pins` with optional parameters: - When no filters are provided, the endpoint will return a small batch of the 10 most recently created items, from the latest to the oldest. - The number of returned items can be adjusted with the `limit` parameter (implicit default is 10). - If the value in `PinResults.count` is bigger than the length of `PinResults.results`, the client can infer there are more results that can be queried. - To read more items, pass the `before` filter with the timestamp from `PinStatus.created` found in the oldest item in the current batch of results. Repeat to read all results. - Returned results can be fine-tuned by applying optional `after`, `cid`, `name`, `status`, or `meta` filters. > **Note**: pagination by the `created` timestamp requires each value to be globally unique. Any future considerations to add support for bulk creation must account for this.
*
* API version: 0.1.1
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"encoding/json"
)
// FailureError struct for FailureError
type FailureError struct {
// Mandatory string identifying the type of error
Reason string `json:"reason"`
// Optional, longer description of the error; may include UUID of transaction for support, links to documentation etc
Details *string `json:"details,omitempty"`
}
// NewFailureError instantiates a new FailureError object
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed
func NewFailureError(reason string) *FailureError {
this := FailureError{}
this.Reason = reason
return &this
}
// NewFailureErrorWithDefaults instantiates a new FailureError object
// This constructor will only assign default values to properties that have it defined,
// but it doesn't guarantee that properties required by API are set
func NewFailureErrorWithDefaults() *FailureError {
this := FailureError{}
return &this
}
// GetReason returns the Reason field value
func (o *FailureError) GetReason() string {
if o == nil {
var ret string
return ret
}
return o.Reason
}
// GetReasonOk returns a tuple with the Reason field value
// and a boolean to check if the value has been set.
func (o *FailureError) GetReasonOk() (*string, bool) {
if o == nil {
return nil, false
}
return &o.Reason, true
}
// SetReason sets field value
func (o *FailureError) SetReason(v string) {
o.Reason = v
}
// GetDetails returns the Details field value if set, zero value otherwise.
func (o *FailureError) GetDetails() string {
if o == nil || o.Details == nil {
var ret string
return ret
}
return *o.Details
}
// GetDetailsOk returns a tuple with the Details field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *FailureError) GetDetailsOk() (*string, bool) {
if o == nil || o.Details == nil {
return nil, false
}
return o.Details, true
}
// HasDetails returns a boolean if a field has been set.
func (o *FailureError) HasDetails() bool {
if o != nil && o.Details != nil {
return true
}
return false
}
// SetDetails gets a reference to the given string and assigns it to the Details field.
func (o *FailureError) SetDetails(v string) {
o.Details = &v
}
func (o FailureError) MarshalJSON() ([]byte, error) {
toSerialize := map[string]interface{}{}
if true {
toSerialize["reason"] = o.Reason
}
if o.Details != nil {
toSerialize["details"] = o.Details
}
return json.Marshal(toSerialize)
}
type NullableFailureError struct {
value *FailureError
isSet bool
}
func (v NullableFailureError) Get() *FailureError {
return v.value
}
func (v *NullableFailureError) Set(val *FailureError) {
v.value = val
v.isSet = true
}
func (v NullableFailureError) IsSet() bool {
return v.isSet
}
func (v *NullableFailureError) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableFailureError(val *FailureError) *NullableFailureError {
return &NullableFailureError{value: val, isSet: true}
}
func (v NullableFailureError) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableFailureError) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}
/*
* IPFS Pinning Service API
*
* ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API&#x3a; - For use and implementation by pinning service providers - For use in client mode by IPFS nodes and GUI-based applications > **Note**: while ready for implementation, this spec is still a work in progress! 🏗️ **Your input and feedback are welcome and valuable as we develop this API spec. Please join the design discussion at [github.com/ipfs/pinning-services-api-spec](https://github.com/ipfs/pinning-services-api-spec).** # Schemas This section describes the most important object types and conventions. A full list of fields and schemas can be found in the `schemas` section of the [YAML file](https://github.com/ipfs/pinning-services-api-spec/blob/master/ipfs-pinning-service.yaml). ## Identifiers ### cid [Content Identifier (CID)](https://docs.ipfs.io/concepts/content-addressing/) points at the root of a DAG that is pinned recursively. ### requestid Unique identifier of a pin request. When a pin is created, the service responds with unique `requestid` that can be later used for pin removal. When the same `cid` is pinned again, a different `requestid` is returned to differentiate between those pin requests. Service implementation should use UUID, `hash(accessToken,Pin,PinStatus.created)`, or any other opaque identifier that provides equally strong protection against race conditions. ## Objects ### Pin object ![pin object](https://bafybeideck2fchyxna4wqwc2mo67yriokehw3yujboc5redjdaajrk2fjq.ipfs.dweb.link/pin.png) The `Pin` object is a representation of a pin request. It includes the `cid` of data to be pinned, as well as optional metadata in `name`, `origins`, and `meta`. ### Pin status response ![pin status response object](https://bafybeideck2fchyxna4wqwc2mo67yriokehw3yujboc5redjdaajrk2fjq.ipfs.dweb.link/pinstatus.png) The `PinStatus` object is a representation of the current state of a pinning operation. It includes the original `pin` object, along with the current `status` and globally unique `requestid` of the entire pinning request, which can be used for future status checks and management. Addresses in the `delegates` array are peers delegated by the pinning service for facilitating direct file transfers (more details in the provider hints section). Any additional vendor-specific information is returned in optional `info`. ## The pin lifecycle ![pinning service objects and lifecycle](https://bafybeideck2fchyxna4wqwc2mo67yriokehw3yujboc5redjdaajrk2fjq.ipfs.dweb.link/lifecycle.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `requestid` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, and removing the pin in the future - `status` in `PinStatus` indicates the current state of a pin ### Checking status of in-progress pinning `status` (in `PinStatus`) may indicate a pending state (`queued` or `pinning`). This means the data behind `Pin.cid` was not found on the pinning service and is being fetched from the IPFS network at large, which may take time. In this case, the user can periodically check pinning progress via `GET /pins/{requestid}` until pinning is successful, or the user decides to remove the pending pin. ### Replacing an existing pin object The user can replace an existing pin object via `POST /pins/{requestid}`. This is a shortcut for removing a pin object identified by `requestid` and creating a new one in a single API call that protects against undesired garbage collection of blocks common to both pins. Useful when updating a pin representing a huge dataset where most of blocks did not change. The new pin object `requestid` is returned in the `PinStatus` response. The old pin object is deleted automatically. ### Removing a pin object A pin object can be removed via `DELETE /pins/{requestid}`. ## Provider hints Pinning of new data can be accelerated by providing a list of known data sources in `Pin.origins`, and connecting at least one of them to pinning service nodes at `PinStatus.delegates`. The most common scenario is a client putting its own IPFS node's multiaddrs in `Pin.origins`, and then directly connecting to every multiaddr returned by a pinning service in `PinStatus.delegates` to initiate transfer. This ensures data transfer starts immediately (without waiting for provider discovery over DHT), and direct dial from a client works around peer routing issues in restrictive network topologies such as NATs. ## Custom metadata Pinning services are encouraged to add support for additional features by leveraging the optional `Pin.meta` and `PinStatus.info` fields. While these attributes can be application- or vendor-specific, we encourage the community at large to leverage these attributes as a sandbox to come up with conventions that could become part of future revisions of this API. ### Pin metadata String keys and values passed in `Pin.meta` are persisted with the pin object. Potential uses: - `Pin.meta[app_id]`: Attaching a unique identifier to pins created by an app enables filtering pins per app via `?meta={\"app_id\":<UUID>}` - `Pin.meta[vendor_policy]`: Vendor-specific policy (for example: which region to use, how many copies to keep) Note that it is OK for a client to omit or ignore these optional attributes; doing so should not impact the basic pinning functionality. ### Pin status info Additional `PinStatus.info` can be returned by pinning service. Potential uses: - `PinStatus.info[status_details]`: more info about the current status (queue position, percentage of transferred data, summary of where data is stored, etc); when `PinStatus.status=failed`, it could provide a reason why a pin operation failed (e.g. lack of funds, DAG too big, etc.) - `PinStatus.info[dag_size]`: the size of pinned data, along with DAG overhead - `PinStatus.info[raw_size]`: the size of data without DAG overhead (eg. unixfs) - `PinStatus.info[pinned_until]`: if vendor supports time-bound pins, this could indicate when the pin will expire # Pagination and filtering Pin objects can be listed by executing `GET /pins` with optional parameters: - When no filters are provided, the endpoint will return a small batch of the 10 most recently created items, from the latest to the oldest. - The number of returned items can be adjusted with the `limit` parameter (implicit default is 10). - If the value in `PinResults.count` is bigger than the length of `PinResults.results`, the client can infer there are more results that can be queried. - To read more items, pass the `before` filter with the timestamp from `PinStatus.created` found in the oldest item in the current batch of results. Repeat to read all results. - Returned results can be fine-tuned by applying optional `after`, `cid`, `name`, `status`, or `meta` filters. > **Note**: pagination by the `created` timestamp requires each value to be globally unique. Any future considerations to add support for bulk creation must account for this.
*
* API version: 0.1.1
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"encoding/json"
)
// Pin Pin object
type Pin struct {
// Content Identifier (CID) to be pinned recursively
Cid string `json:"cid"`
// Optional name for pinned data; can be used for lookups later
Name *string `json:"name,omitempty"`
// Optional list of multiaddrs known to provide the data
Origins *[]string `json:"origins,omitempty"`
// Optional metadata for pin object
Meta *map[string]string `json:"meta,omitempty"`
}
// NewPin instantiates a new Pin object
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed
func NewPin(cid string) *Pin {
this := Pin{}
this.Cid = cid
return &this
}
// NewPinWithDefaults instantiates a new Pin object
// This constructor will only assign default values to properties that have it defined,
// but it doesn't guarantee that properties required by API are set
func NewPinWithDefaults() *Pin {
this := Pin{}
return &this
}
// GetCid returns the Cid field value
func (o *Pin) GetCid() string {
if o == nil {
var ret string
return ret
}
return o.Cid
}
// GetCidOk returns a tuple with the Cid field value
// and a boolean to check if the value has been set.
func (o *Pin) GetCidOk() (*string, bool) {
if o == nil {
return nil, false
}
return &o.Cid, true
}
// SetCid sets field value
func (o *Pin) SetCid(v string) {
o.Cid = v
}
// GetName returns the Name field value if set, zero value otherwise.
func (o *Pin) GetName() string {
if o == nil || o.Name == nil {
var ret string
return ret
}
return *o.Name
}
// GetNameOk returns a tuple with the Name field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *Pin) GetNameOk() (*string, bool) {
if o == nil || o.Name == nil {
return nil, false
}
return o.Name, true
}
// HasName returns a boolean if a field has been set.
func (o *Pin) HasName() bool {
if o != nil && o.Name != nil {
return true
}
return false
}
// SetName gets a reference to the given string and assigns it to the Name field.
func (o *Pin) SetName(v string) {
o.Name = &v
}
// GetOrigins returns the Origins field value if set, zero value otherwise.
func (o *Pin) GetOrigins() []string {
if o == nil || o.Origins == nil {
var ret []string
return ret
}
return *o.Origins
}
// GetOriginsOk returns a tuple with the Origins field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *Pin) GetOriginsOk() (*[]string, bool) {
if o == nil || o.Origins == nil {
return nil, false
}
return o.Origins, true
}
// HasOrigins returns a boolean if a field has been set.
func (o *Pin) HasOrigins() bool {
if o != nil && o.Origins != nil {
return true
}
return false
}
// SetOrigins gets a reference to the given []string and assigns it to the Origins field.
func (o *Pin) SetOrigins(v []string) {
o.Origins = &v
}
// GetMeta returns the Meta field value if set, zero value otherwise.
func (o *Pin) GetMeta() map[string]string {
if o == nil || o.Meta == nil {
var ret map[string]string
return ret
}
return *o.Meta
}
// GetMetaOk returns a tuple with the Meta field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *Pin) GetMetaOk() (*map[string]string, bool) {
if o == nil || o.Meta == nil {
return nil, false
}
return o.Meta, true
}
// HasMeta returns a boolean if a field has been set.
func (o *Pin) HasMeta() bool {
if o != nil && o.Meta != nil {
return true
}
return false
}
// SetMeta gets a reference to the given map[string]string and assigns it to the Meta field.
func (o *Pin) SetMeta(v map[string]string) {
o.Meta = &v
}
func (o Pin) MarshalJSON() ([]byte, error) {
toSerialize := map[string]interface{}{}
if true {
toSerialize["cid"] = o.Cid
}
if o.Name != nil {
toSerialize["name"] = o.Name
}
if o.Origins != nil {
toSerialize["origins"] = o.Origins
}
if o.Meta != nil {
toSerialize["meta"] = o.Meta
}
return json.Marshal(toSerialize)
}
type NullablePin struct {
value *Pin
isSet bool
}
func (v NullablePin) Get() *Pin {
return v.value
}
func (v *NullablePin) Set(val *Pin) {
v.value = val
v.isSet = true
}
func (v NullablePin) IsSet() bool {
return v.isSet
}
func (v *NullablePin) Unset() {
v.value = nil
v.isSet = false
}
func NewNullablePin(val *Pin) *NullablePin {
return &NullablePin{value: val, isSet: true}
}
func (v NullablePin) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullablePin) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* IPFS Pinning Service API
*
* ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API&#x3a; - For use and implementation by pinning service providers - For use in client mode by IPFS nodes and GUI-based applications > **Note**: while ready for implementation, this spec is still a work in progress! 🏗️ **Your input and feedback are welcome and valuable as we develop this API spec. Please join the design discussion at [github.com/ipfs/pinning-services-api-spec](https://github.com/ipfs/pinning-services-api-spec).** # Schemas This section describes the most important object types and conventions. A full list of fields and schemas can be found in the `schemas` section of the [YAML file](https://github.com/ipfs/pinning-services-api-spec/blob/master/ipfs-pinning-service.yaml). ## Identifiers ### cid [Content Identifier (CID)](https://docs.ipfs.io/concepts/content-addressing/) points at the root of a DAG that is pinned recursively. ### requestid Unique identifier of a pin request. When a pin is created, the service responds with unique `requestid` that can be later used for pin removal. When the same `cid` is pinned again, a different `requestid` is returned to differentiate between those pin requests. Service implementation should use UUID, `hash(accessToken,Pin,PinStatus.created)`, or any other opaque identifier that provides equally strong protection against race conditions. ## Objects ### Pin object ![pin object](https://bafybeideck2fchyxna4wqwc2mo67yriokehw3yujboc5redjdaajrk2fjq.ipfs.dweb.link/pin.png) The `Pin` object is a representation of a pin request. It includes the `cid` of data to be pinned, as well as optional metadata in `name`, `origins`, and `meta`. ### Pin status response ![pin status response object](https://bafybeideck2fchyxna4wqwc2mo67yriokehw3yujboc5redjdaajrk2fjq.ipfs.dweb.link/pinstatus.png) The `PinStatus` object is a representation of the current state of a pinning operation. It includes the original `pin` object, along with the current `status` and globally unique `requestid` of the entire pinning request, which can be used for future status checks and management. Addresses in the `delegates` array are peers delegated by the pinning service for facilitating direct file transfers (more details in the provider hints section). Any additional vendor-specific information is returned in optional `info`. ## The pin lifecycle ![pinning service objects and lifecycle](https://bafybeideck2fchyxna4wqwc2mo67yriokehw3yujboc5redjdaajrk2fjq.ipfs.dweb.link/lifecycle.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `requestid` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, and removing the pin in the future - `status` in `PinStatus` indicates the current state of a pin ### Checking status of in-progress pinning `status` (in `PinStatus`) may indicate a pending state (`queued` or `pinning`). This means the data behind `Pin.cid` was not found on the pinning service and is being fetched from the IPFS network at large, which may take time. In this case, the user can periodically check pinning progress via `GET /pins/{requestid}` until pinning is successful, or the user decides to remove the pending pin. ### Replacing an existing pin object The user can replace an existing pin object via `POST /pins/{requestid}`. This is a shortcut for removing a pin object identified by `requestid` and creating a new one in a single API call that protects against undesired garbage collection of blocks common to both pins. Useful when updating a pin representing a huge dataset where most of blocks did not change. The new pin object `requestid` is returned in the `PinStatus` response. The old pin object is deleted automatically. ### Removing a pin object A pin object can be removed via `DELETE /pins/{requestid}`. ## Provider hints Pinning of new data can be accelerated by providing a list of known data sources in `Pin.origins`, and connecting at least one of them to pinning service nodes at `PinStatus.delegates`. The most common scenario is a client putting its own IPFS node's multiaddrs in `Pin.origins`, and then directly connecting to every multiaddr returned by a pinning service in `PinStatus.delegates` to initiate transfer. This ensures data transfer starts immediately (without waiting for provider discovery over DHT), and direct dial from a client works around peer routing issues in restrictive network topologies such as NATs. ## Custom metadata Pinning services are encouraged to add support for additional features by leveraging the optional `Pin.meta` and `PinStatus.info` fields. While these attributes can be application- or vendor-specific, we encourage the community at large to leverage these attributes as a sandbox to come up with conventions that could become part of future revisions of this API. ### Pin metadata String keys and values passed in `Pin.meta` are persisted with the pin object. Potential uses: - `Pin.meta[app_id]`: Attaching a unique identifier to pins created by an app enables filtering pins per app via `?meta={\"app_id\":<UUID>}` - `Pin.meta[vendor_policy]`: Vendor-specific policy (for example: which region to use, how many copies to keep) Note that it is OK for a client to omit or ignore these optional attributes; doing so should not impact the basic pinning functionality. ### Pin status info Additional `PinStatus.info` can be returned by pinning service. Potential uses: - `PinStatus.info[status_details]`: more info about the current status (queue position, percentage of transferred data, summary of where data is stored, etc); when `PinStatus.status=failed`, it could provide a reason why a pin operation failed (e.g. lack of funds, DAG too big, etc.) - `PinStatus.info[dag_size]`: the size of pinned data, along with DAG overhead - `PinStatus.info[raw_size]`: the size of data without DAG overhead (eg. unixfs) - `PinStatus.info[pinned_until]`: if vendor supports time-bound pins, this could indicate when the pin will expire # Pagination and filtering Pin objects can be listed by executing `GET /pins` with optional parameters: - When no filters are provided, the endpoint will return a small batch of the 10 most recently created items, from the latest to the oldest. - The number of returned items can be adjusted with the `limit` parameter (implicit default is 10). - If the value in `PinResults.count` is bigger than the length of `PinResults.results`, the client can infer there are more results that can be queried. - To read more items, pass the `before` filter with the timestamp from `PinStatus.created` found in the oldest item in the current batch of results. Repeat to read all results. - Returned results can be fine-tuned by applying optional `after`, `cid`, `name`, `status`, or `meta` filters. > **Note**: pagination by the `created` timestamp requires each value to be globally unique. Any future considerations to add support for bulk creation must account for this.
*
* API version: 0.1.1
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package openapi
import (
"net/http"
)
// APIResponse stores the API response returned by the server.
type APIResponse struct {
*http.Response `json:"-"`
Message string `json:"message,omitempty"`
// Operation is the name of the OpenAPI operation.
Operation string `json:"operation,omitempty"`
// RequestURL is the request URL. This value is always available, even if the
// embedded *http.Response is nil.
RequestURL string `json:"url,omitempty"`
// Method is the HTTP method used for the request. This value is always
// available, even if the embedded *http.Response is nil.
Method string `json:"method,omitempty"`
// Payload holds the contents of the response body (which may be nil or empty).
// This is provided here as the raw response.Body() reader will have already
// been drained.
Payload []byte `json:"-"`
}
// NewAPIResponse returns a new APIResonse object.
func NewAPIResponse(r *http.Response) *APIResponse {
response := &APIResponse{Response: r}
return response
}
// NewAPIResponseWithError returns a new APIResponse object with the provided error message.
func NewAPIResponseWithError(errorMessage string) *APIResponse {
response := &APIResponse{Message: errorMessage}
return response
}
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment