From aaa4dcd596eed9264dd196cb1c1b53b293b9562e Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Mon, 21 Sep 2020 13:07:01 -0400 Subject: [PATCH 1/8] init: use template for the dual Apache-MIT license and basic README This commit was moved from ipfs/go-pinning-service-http-client@4ebc72023aa7f7ecb39edcfe7f133ddfb3eceb65 --- pinning/remote/client/LICENSE | 35 +++++++++++++++++---------------- pinning/remote/client/README.md | 20 +++++++++++++++++++ 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/pinning/remote/client/LICENSE b/pinning/remote/client/LICENSE index 2b5d8a7da..1f34f7186 100644 --- a/pinning/remote/client/LICENSE +++ b/pinning/remote/client/LICENSE @@ -1,21 +1,22 @@ -MIT License +The software contents of this repository are Copyright (c) Protocol Labs, +Licensed under the `Permissive License Stack`, meaning either of: -Copyright (c) 2020 IPFS +- Apache-2.0 Software License: https://www.apache.org/licenses/LICENSE-2.0 + ([...4tr2kfsq](https://gateway.ipfs.io/ipfs/bafkreiankqxazcae4onkp436wag2lj3ccso4nawxqkkfckd6cg4tr2kfsq)) -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +- MIT Software License: https://opensource.org/licenses/MIT + ([...vljevcba](https://gateway.ipfs.io/ipfs/bafkreiepofszg4gfe2gzuhojmksgemsub2h4uy2gewdnr35kswvljevcba)) -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +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/ -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +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` \ No newline at end of file diff --git a/pinning/remote/client/README.md b/pinning/remote/client/README.md index 0a2542a8a..213f0df83 100644 --- a/pinning/remote/client/README.md +++ b/pinning/remote/client/README.md @@ -1,2 +1,22 @@ # 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) + +## 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) \ No newline at end of file From 67cf885fb723b295db69cd8d2e1791b4d66c9f39 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Sat, 29 Aug 2020 21:25:37 -0400 Subject: [PATCH 2/8] feat: initial implementation This commit was moved from ipfs/go-pinning-service-http-client@08125a6c7413fc6b06db906e9feee0b8eaebb050 --- pinning/remote/client/client.go | 376 +++++++++ pinning/remote/client/cmd/main.go | 77 ++ pinning/remote/client/model.go | 79 ++ pinning/remote/client/openapi/README.md | 205 +++++ pinning/remote/client/openapi/api_pins.go | 781 ++++++++++++++++++ pinning/remote/client/openapi/client.go | 531 ++++++++++++ .../remote/client/openapi/configuration.go | 228 +++++ pinning/remote/client/openapi/docs/Error.md | 72 ++ pinning/remote/client/openapi/docs/Pin.md | 129 +++ .../remote/client/openapi/docs/PinResults.md | 72 ++ .../remote/client/openapi/docs/PinStatus.md | 161 ++++ pinning/remote/client/openapi/docs/PinsApi.md | 367 ++++++++ pinning/remote/client/openapi/docs/Status.md | 11 + pinning/remote/client/openapi/model_error.go | 134 +++ pinning/remote/client/openapi/model_pin.go | 217 +++++ .../client/openapi/model_pin_results.go | 136 +++ .../remote/client/openapi/model_pin_status.go | 262 ++++++ pinning/remote/client/openapi/model_status.go | 84 ++ pinning/remote/client/openapi/response.go | 46 ++ pinning/remote/client/openapi/utils.go | 327 ++++++++ 20 files changed, 4295 insertions(+) create mode 100644 pinning/remote/client/client.go create mode 100644 pinning/remote/client/cmd/main.go create mode 100644 pinning/remote/client/model.go create mode 100644 pinning/remote/client/openapi/README.md create mode 100644 pinning/remote/client/openapi/api_pins.go create mode 100644 pinning/remote/client/openapi/client.go create mode 100644 pinning/remote/client/openapi/configuration.go create mode 100644 pinning/remote/client/openapi/docs/Error.md create mode 100644 pinning/remote/client/openapi/docs/Pin.md create mode 100644 pinning/remote/client/openapi/docs/PinResults.md create mode 100644 pinning/remote/client/openapi/docs/PinStatus.md create mode 100644 pinning/remote/client/openapi/docs/PinsApi.md create mode 100644 pinning/remote/client/openapi/docs/Status.md create mode 100644 pinning/remote/client/openapi/model_error.go create mode 100644 pinning/remote/client/openapi/model_pin.go create mode 100644 pinning/remote/client/openapi/model_pin_results.go create mode 100644 pinning/remote/client/openapi/model_pin_status.go create mode 100644 pinning/remote/client/openapi/model_status.go create mode 100644 pinning/remote/client/openapi/response.go create mode 100644 pinning/remote/client/openapi/utils.go diff --git a/pinning/remote/client/client.go b/pinning/remote/client/client.go new file mode 100644 index 000000000..b4fa37830 --- /dev/null +++ b/pinning/remote/client/client.go @@ -0,0 +1,376 @@ +package go_pinning_service_http_client + +import ( + "context" + "fmt" + "io/ioutil" + "net/http" + "time" + + "github.com/ipfs/go-cid" + "github.com/ipfs/go-pinning-service-http-client/openapi" + "github.com/multiformats/go-multiaddr" + "github.com/multiformats/go-multibase" + + logging "github.com/ipfs/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)} +} + +func getError(e *openapi.Error) error { + return fmt.Errorf("request error: %d - %s", e.Code, e.Message) +} + +// 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 +} + +func (c *Client) lsInternal(ctx context.Context, settings *lsSettings) (pinResults, error) { + getter := c.client.PinsApi.PinsGet(ctx) + if len(settings.cids) > 0 { + getter.Cid(settings.cids) + } + if len(settings.status) > 0 { + getter.Status(settings.status) + } + if settings.limit == nil { + getter.Limit(defaultLimit) + } else { + getter.Limit(*settings.limit) + } + if len(settings.name) > 0 { + getter.Name(settings.name) + } + if settings.before != nil { + getter.Before(*settings.before) + } + if settings.after != nil { + getter.After(*settings.after) + } + if settings.meta != nil { + 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 (pinLsOpts) 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.PinsIdGet(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.PinsIdDelete(ctx, pinID) + httpresp, err := deleter.Execute() + if err != nil { + err := httperr(httpresp, err) + return err + } + return nil +} + +func (c *Client) Modify(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.PinsIdPost(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 { + body, err := ioutil.ReadAll(resp.Body) + var bodystr string + if err == nil { + bodystr = string(body) + } + return fmt.Errorf("httpresp code: %d, httpresp: %s, httpbody: %s, err: %w", resp.StatusCode, resp.Status, bodystr, e) +} diff --git a/pinning/remote/client/cmd/main.go b/pinning/remote/client/cmd/main.go new file mode 100644 index 000000000..fefd9503d --- /dev/null +++ b/pinning/remote/client/cmd/main.go @@ -0,0 +1,77 @@ +package main + +import ( + "context" + "fmt" + "github.com/ipfs/go-cid" + pinclient "github.com/ipfs/go-pinning-service-http-client" + "os" +) + +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) + + ipfsPgCid, err := cid.Parse("bafybeiayvrj27f65vbecspbnuavehcb3znvnt2strop2rfbczupudoizya") + if err != nil { + panic(err) + } + + libp2pCid, err := cid.Parse("bafybeiejgrxo4p4uofgfzvlg5twrg5w7tfwpf7aciiswfacfbdpevg2xfy") + if err != nil { + panic(err) + } + _ = ipfsPgCid + + fmt.Println("Adding libp2p home page") + ps, err := c.Add(ctx, libp2pCid, pinclient.PinOpts.WithName("libp2p_home")) + if err == nil { + fmt.Println(ps.GetStatus()) + } else { + fmt.Println(err) + } + + fmt.Println("List all pins") + pins, err := c.LsSync(ctx) + fmt.Println(err) + + for _, p := range pins { + fmt.Printf("Pin Name: %s, CID: %s", p.GetPin().GetName(), p.GetPin().GetCid().String()) + } + + fmt.Println("Check on pin status") + status, err := c.GetStatusByID(ctx, ps.GetId()) + if err == nil { + fmt.Println(status.GetStatus()) + } else { + fmt.Println(err) + } + + fmt.Println("Delete pin") + err = c.DeleteByID(ctx, ps.GetId()) + if err == nil { + fmt.Println("Successfully deleted pin") + } else { + fmt.Println(err) + } + + fmt.Println("List all pins") + pins, err = c.LsSync(ctx) + fmt.Println(err) + + for _, p := range pins { + fmt.Printf("Pin Name: %s, CID: %s", p.GetPin().GetName(), p.GetPin().GetCid().String()) + } +} diff --git a/pinning/remote/client/model.go b/pinning/remote/client/model.go new file mode 100644 index 000000000..e6c552d51 --- /dev/null +++ b/pinning/remote/client/model.go @@ -0,0 +1,79 @@ +package go_pinning_service_http_client + +import ( + "github.com/ipfs/go-cid" + "github.com/ipfs/go-pinning-service-http-client/openapi" + "github.com/multiformats/go-multiaddr" + "time" +) + +// PinGetter Getter for Pin object +type PinGetter interface { + // 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) GetCid() cid.Cid { + c, err := cid.Parse(p.Pin.Cid) + if err != nil { + return cid.Undef + } + return c +} + +type Status = openapi.Status + +const ( + StatusQueued Status = openapi.QUEUED + StatusPinning Status = openapi.PINNING + StatusPinned Status = openapi.PINNED + StatusFailed Status = openapi.FAILED +) + +var validStatuses = []Status{"queued", "pinning", "pinned", "failed"} + +// PinStatusGetter Getter for Pin object with status +type PinStatusGetter interface { + // Globally unique ID of the pin request; can be used to check the status of ongoing pinning, modification of pin object, or pin removal + GetId() 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} +} diff --git a/pinning/remote/client/openapi/README.md b/pinning/remote/client/openapi/README.md new file mode 100644 index 000000000..64e843f88 --- /dev/null +++ b/pinning/remote/client/openapi/README.md @@ -0,0 +1,205 @@ +# Go API client for openapi + + + +## About this spec +The IPFS Pinning Service API is intended to be an implementation-agnostic API: +- 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). +## Objects +### Pin object + +![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 + +![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) + +### Creating a new pin object +The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: +- `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. + +### Modifying an existing pin object +The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. + + +## 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\":}` +- `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.0.5 +- 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* | [**PinsIdDelete**](docs/PinsApi.md#pinsiddelete) | **Delete** /pins/{id} | Remove pin object +*PinsApi* | [**PinsIdGet**](docs/PinsApi.md#pinsidget) | **Get** /pins/{id} | Get pin object +*PinsApi* | [**PinsIdPost**](docs/PinsApi.md#pinsidpost) | **Post** /pins/{id} | Modify pin object +*PinsApi* | [**PinsPost**](docs/PinsApi.md#pinspost) | **Post** /pins | Add pin object + + +## Documentation For Models + + - [Error](docs/Error.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 + + + diff --git a/pinning/remote/client/openapi/api_pins.go b/pinning/remote/client/openapi/api_pins.go new file mode 100644 index 000000000..623862df7 --- /dev/null +++ b/pinning/remote/client/openapi/api_pins.go @@ -0,0 +1,781 @@ +/* + * IPFS Pinning Service API + * + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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.0.5 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + _context "context" + _ioutil "io/ioutil" + _nethttp "net/http" + _neturl "net/url" + "strings" + "time" +) + +// Linger please +var ( + _ _context.Context +) + +// PinsApiService PinsApi service +type PinsApiService service + +type apiPinsGetRequest struct { + ctx _context.Context + apiService *PinsApiService + cid *[]string + name *string + status *[]Status + before *time.Time + after *time.Time + limit *int32 + meta *map[string]string +} + +func (r apiPinsGetRequest) Cid(cid []string) apiPinsGetRequest { + r.cid = &cid + return r +} + +func (r apiPinsGetRequest) Name(name string) apiPinsGetRequest { + r.name = &name + return r +} + +func (r apiPinsGetRequest) Status(status []Status) apiPinsGetRequest { + r.status = &status + return r +} + +func (r apiPinsGetRequest) Before(before time.Time) apiPinsGetRequest { + r.before = &before + return r +} + +func (r apiPinsGetRequest) After(after time.Time) apiPinsGetRequest { + r.after = &after + return r +} + +func (r apiPinsGetRequest) Limit(limit int32) apiPinsGetRequest { + r.limit = &limit + return r +} + +func (r apiPinsGetRequest) Meta(meta map[string]string) apiPinsGetRequest { + r.meta = &meta + return r +} + +/* +PinsGet List pin objects +List all the pin objects, matching optional filters; when no filter is provided, only successful pins are returned + * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). +@return apiPinsGetRequest +*/ +func (a *PinsApiService) PinsGet(ctx _context.Context) apiPinsGetRequest { + return apiPinsGetRequest{ + apiService: a, + ctx: ctx, + } +} + +/* +Execute executes the request + @return PinResults +*/ +func (r apiPinsGetRequest) Execute() (PinResults, *_nethttp.Response, error) { + var ( + localVarHTTPMethod = _nethttp.MethodGet + localVarPostBody interface{} + localVarFormFileName string + localVarFileName string + localVarFileBytes []byte + localVarReturnValue PinResults + ) + + localBasePath, err := r.apiService.client.cfg.ServerURLWithContext(r.ctx, "PinsApiService.PinsGet") + if err != nil { + return localVarReturnValue, nil, GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/pins" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := _neturl.Values{} + localVarFormParams := _neturl.Values{} + + if r.cid != nil { + localVarQueryParams.Add("cid", parameterToString(*r.cid, "csv")) + } + if r.name != nil { + localVarQueryParams.Add("name", parameterToString(*r.name, "")) + } + if r.status != nil { + localVarQueryParams.Add("status", parameterToString(*r.status, "csv")) + } + if r.before != nil { + localVarQueryParams.Add("before", parameterToString(*r.before, "")) + } + if r.after != nil { + localVarQueryParams.Add("after", parameterToString(*r.after, "")) + } + if r.limit != nil { + localVarQueryParams.Add("limit", parameterToString(*r.limit, "")) + } + if r.meta != nil { + localVarQueryParams.Add("meta", parameterToString(*r.meta, "")) + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := r.apiService.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := r.apiService.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = r.apiService.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type apiPinsIdDeleteRequest struct { + ctx _context.Context + apiService *PinsApiService + id string +} + +/* +PinsIdDelete Remove pin object +Remove a pin object + * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param id +@return apiPinsIdDeleteRequest +*/ +func (a *PinsApiService) PinsIdDelete(ctx _context.Context, id string) apiPinsIdDeleteRequest { + return apiPinsIdDeleteRequest{ + apiService: a, + ctx: ctx, + id: id, + } +} + +/* +Execute executes the request + +*/ +func (r apiPinsIdDeleteRequest) Execute() (*_nethttp.Response, error) { + var ( + localVarHTTPMethod = _nethttp.MethodDelete + localVarPostBody interface{} + localVarFormFileName string + localVarFileName string + localVarFileBytes []byte + ) + + localBasePath, err := r.apiService.client.cfg.ServerURLWithContext(r.ctx, "PinsApiService.PinsIdDelete") + if err != nil { + return nil, GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/pins/{id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", _neturl.PathEscape(parameterToString(r.id, "")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := _neturl.Values{} + localVarFormParams := _neturl.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := r.apiService.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := r.apiService.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.model = v + return localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.model = v + return localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.model = v + return localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.model = v + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + +type apiPinsIdGetRequest struct { + ctx _context.Context + apiService *PinsApiService + id string +} + +/* +PinsIdGet Get pin object +Get a pin object and its status + * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param id +@return apiPinsIdGetRequest +*/ +func (a *PinsApiService) PinsIdGet(ctx _context.Context, id string) apiPinsIdGetRequest { + return apiPinsIdGetRequest{ + apiService: a, + ctx: ctx, + id: id, + } +} + +/* +Execute executes the request + @return PinStatus +*/ +func (r apiPinsIdGetRequest) Execute() (PinStatus, *_nethttp.Response, error) { + var ( + localVarHTTPMethod = _nethttp.MethodGet + localVarPostBody interface{} + localVarFormFileName string + localVarFileName string + localVarFileBytes []byte + localVarReturnValue PinStatus + ) + + localBasePath, err := r.apiService.client.cfg.ServerURLWithContext(r.ctx, "PinsApiService.PinsIdGet") + if err != nil { + return localVarReturnValue, nil, GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/pins/{id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", _neturl.PathEscape(parameterToString(r.id, "")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := _neturl.Values{} + localVarFormParams := _neturl.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := r.apiService.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := r.apiService.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = r.apiService.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type apiPinsIdPostRequest struct { + ctx _context.Context + apiService *PinsApiService + id string + pin *Pin +} + +func (r apiPinsIdPostRequest) Pin(pin Pin) apiPinsIdPostRequest { + r.pin = &pin + return r +} + +/* +PinsIdPost Modify pin object +Modify an existing pin object + * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param id +@return apiPinsIdPostRequest +*/ +func (a *PinsApiService) PinsIdPost(ctx _context.Context, id string) apiPinsIdPostRequest { + return apiPinsIdPostRequest{ + apiService: a, + ctx: ctx, + id: id, + } +} + +/* +Execute executes the request + @return PinStatus +*/ +func (r apiPinsIdPostRequest) Execute() (PinStatus, *_nethttp.Response, error) { + var ( + localVarHTTPMethod = _nethttp.MethodPost + localVarPostBody interface{} + localVarFormFileName string + localVarFileName string + localVarFileBytes []byte + localVarReturnValue PinStatus + ) + + localBasePath, err := r.apiService.client.cfg.ServerURLWithContext(r.ctx, "PinsApiService.PinsIdPost") + if err != nil { + return localVarReturnValue, nil, GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/pins/{id}" + localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", _neturl.PathEscape(parameterToString(r.id, "")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := _neturl.Values{} + localVarFormParams := _neturl.Values{} + + if r.pin == nil { + return localVarReturnValue, nil, reportError("pin is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.pin + req, err := r.apiService.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := r.apiService.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 409 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = r.apiService.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type apiPinsPostRequest struct { + ctx _context.Context + apiService *PinsApiService + pin *Pin +} + +func (r apiPinsPostRequest) Pin(pin Pin) apiPinsPostRequest { + r.pin = &pin + return r +} + +/* +PinsPost Add pin object +Add a new pin object for the current access token + * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). +@return apiPinsPostRequest +*/ +func (a *PinsApiService) PinsPost(ctx _context.Context) apiPinsPostRequest { + return apiPinsPostRequest{ + apiService: a, + ctx: ctx, + } +} + +/* +Execute executes the request + @return PinStatus +*/ +func (r apiPinsPostRequest) Execute() (PinStatus, *_nethttp.Response, error) { + var ( + localVarHTTPMethod = _nethttp.MethodPost + localVarPostBody interface{} + localVarFormFileName string + localVarFileName string + localVarFileBytes []byte + localVarReturnValue PinStatus + ) + + localBasePath, err := r.apiService.client.cfg.ServerURLWithContext(r.ctx, "PinsApiService.PinsPost") + if err != nil { + return localVarReturnValue, nil, GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/pins" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := _neturl.Values{} + localVarFormParams := _neturl.Values{} + + if r.pin == nil { + return localVarReturnValue, nil, reportError("pin is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.pin + req, err := r.apiService.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := r.apiService.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 409 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = r.apiService.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} diff --git a/pinning/remote/client/openapi/client.go b/pinning/remote/client/openapi/client.go new file mode 100644 index 000000000..2fa0b79ab --- /dev/null +++ b/pinning/remote/client/openapi/client.go @@ -0,0 +1,531 @@ +/* + * IPFS Pinning Service API + * + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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.0.5 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "bytes" + "context" + "encoding/json" + "encoding/xml" + "errors" + "fmt" + "io" + "log" + "mime/multipart" + "net/http" + "net/http/httputil" + "net/url" + "os" + "path/filepath" + "reflect" + "regexp" + "strconv" + "strings" + "time" + "unicode/utf8" + + "golang.org/x/oauth2" +) + +var ( + jsonCheck = regexp.MustCompile(`(?i:(?:application|text)/(?:vnd\.[^;]+\+)?json)`) + xmlCheck = regexp.MustCompile(`(?i:(?:application|text)/xml)`) +) + +// APIClient manages communication with the IPFS Pinning Service API API v0.0.5 +// In most cases there should be only one, shared, APIClient. +type APIClient struct { + cfg *Configuration + common service // Reuse a single struct instead of allocating one for each service on the heap. + + // API Services + + PinsApi *PinsApiService +} + +type service struct { + client *APIClient +} + +// NewAPIClient creates a new API client. Requires a userAgent string describing your application. +// optionally a custom http.Client to allow for advanced features such as caching. +func NewAPIClient(cfg *Configuration) *APIClient { + if cfg.HTTPClient == nil { + cfg.HTTPClient = http.DefaultClient + } + + c := &APIClient{} + c.cfg = cfg + c.common.client = c + + // API Services + c.PinsApi = (*PinsApiService)(&c.common) + + return c +} + +func atoi(in string) (int, error) { + return strconv.Atoi(in) +} + +// selectHeaderContentType select a content type from the available list. +func selectHeaderContentType(contentTypes []string) string { + if len(contentTypes) == 0 { + return "" + } + if contains(contentTypes, "application/json") { + return "application/json" + } + return contentTypes[0] // use the first content type specified in 'consumes' +} + +// selectHeaderAccept join all accept types and return +func selectHeaderAccept(accepts []string) string { + if len(accepts) == 0 { + return "" + } + + if contains(accepts, "application/json") { + return "application/json" + } + + return strings.Join(accepts, ",") +} + +// contains is a case insenstive match, finding needle in a haystack +func contains(haystack []string, needle string) bool { + for _, a := range haystack { + if strings.ToLower(a) == strings.ToLower(needle) { + return true + } + } + return false +} + +// Verify optional parameters are of the correct type. +func typeCheckParameter(obj interface{}, expected string, name string) error { + // Make sure there is an object. + if obj == nil { + return nil + } + + // Check the type is as expected. + if reflect.TypeOf(obj).String() != expected { + return fmt.Errorf("Expected %s to be of type %s but received %s.", name, expected, reflect.TypeOf(obj).String()) + } + return nil +} + +// parameterToString convert interface{} parameters to string, using a delimiter if format is provided. +func parameterToString(obj interface{}, collectionFormat string) string { + var delimiter string + + switch collectionFormat { + case "pipes": + delimiter = "|" + case "ssv": + delimiter = " " + case "tsv": + delimiter = "\t" + case "csv": + delimiter = "," + } + + if reflect.TypeOf(obj).Kind() == reflect.Slice { + return strings.Trim(strings.Replace(fmt.Sprint(obj), " ", delimiter, -1), "[]") + } else if t, ok := obj.(time.Time); ok { + return t.Format(time.RFC3339) + } + + return fmt.Sprintf("%v", obj) +} + +// helper for converting interface{} parameters to json strings +func parameterToJson(obj interface{}) (string, error) { + jsonBuf, err := json.Marshal(obj) + if err != nil { + return "", err + } + return string(jsonBuf), err +} + +// callAPI do the request. +func (c *APIClient) callAPI(request *http.Request) (*http.Response, error) { + if c.cfg.Debug { + dump, err := httputil.DumpRequestOut(request, true) + if err != nil { + return nil, err + } + log.Printf("\n%s\n", string(dump)) + } + + resp, err := c.cfg.HTTPClient.Do(request) + if err != nil { + return resp, err + } + + if c.cfg.Debug { + dump, err := httputil.DumpResponse(resp, true) + if err != nil { + return resp, err + } + log.Printf("\n%s\n", string(dump)) + } + return resp, err +} + +// Allow modification of underlying config for alternate implementations and testing +// Caution: modifying the configuration while live can cause data races and potentially unwanted behavior +func (c *APIClient) GetConfig() *Configuration { + return c.cfg +} + +// prepareRequest build the request +func (c *APIClient) prepareRequest( + ctx context.Context, + path string, method string, + postBody interface{}, + headerParams map[string]string, + queryParams url.Values, + formParams url.Values, + formFileName string, + fileName string, + fileBytes []byte) (localVarRequest *http.Request, err error) { + + var body *bytes.Buffer + + // Detect postBody type and post. + if postBody != nil { + contentType := headerParams["Content-Type"] + if contentType == "" { + contentType = detectContentType(postBody) + headerParams["Content-Type"] = contentType + } + + body, err = setBody(postBody, contentType) + if err != nil { + return nil, err + } + } + + // add form parameters and file if available. + if strings.HasPrefix(headerParams["Content-Type"], "multipart/form-data") && len(formParams) > 0 || (len(fileBytes) > 0 && fileName != "") { + if body != nil { + return nil, errors.New("Cannot specify postBody and multipart form at the same time.") + } + body = &bytes.Buffer{} + w := multipart.NewWriter(body) + + for k, v := range formParams { + for _, iv := range v { + if strings.HasPrefix(k, "@") { // file + err = addFile(w, k[1:], iv) + if err != nil { + return nil, err + } + } else { // form value + w.WriteField(k, iv) + } + } + } + if len(fileBytes) > 0 && fileName != "" { + w.Boundary() + //_, fileNm := filepath.Split(fileName) + part, err := w.CreateFormFile(formFileName, filepath.Base(fileName)) + if err != nil { + return nil, err + } + _, err = part.Write(fileBytes) + if err != nil { + return nil, err + } + } + + // Set the Boundary in the Content-Type + headerParams["Content-Type"] = w.FormDataContentType() + + // Set Content-Length + headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len()) + w.Close() + } + + if strings.HasPrefix(headerParams["Content-Type"], "application/x-www-form-urlencoded") && len(formParams) > 0 { + if body != nil { + return nil, errors.New("Cannot specify postBody and x-www-form-urlencoded form at the same time.") + } + body = &bytes.Buffer{} + body.WriteString(formParams.Encode()) + // Set Content-Length + headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len()) + } + + // Setup path and query parameters + url, err := url.Parse(path) + if err != nil { + return nil, err + } + + // Override request host, if applicable + if c.cfg.Host != "" { + url.Host = c.cfg.Host + } + + // Override request scheme, if applicable + if c.cfg.Scheme != "" { + url.Scheme = c.cfg.Scheme + } + + // Adding Query Param + query := url.Query() + for k, v := range queryParams { + for _, iv := range v { + query.Add(k, iv) + } + } + + // Encode the parameters. + url.RawQuery = query.Encode() + + // Generate a new request + if body != nil { + localVarRequest, err = http.NewRequest(method, url.String(), body) + } else { + localVarRequest, err = http.NewRequest(method, url.String(), nil) + } + if err != nil { + return nil, err + } + + // add header parameters, if any + if len(headerParams) > 0 { + headers := http.Header{} + for h, v := range headerParams { + headers.Set(h, v) + } + localVarRequest.Header = headers + } + + // Add the user agent to the request. + localVarRequest.Header.Add("User-Agent", c.cfg.UserAgent) + + if ctx != nil { + // add context to the request + localVarRequest = localVarRequest.WithContext(ctx) + + // Walk through any authentication. + + // OAuth2 authentication + if tok, ok := ctx.Value(ContextOAuth2).(oauth2.TokenSource); ok { + // We were able to grab an oauth2 token from the context + var latestToken *oauth2.Token + if latestToken, err = tok.Token(); err != nil { + return nil, err + } + + latestToken.SetAuthHeader(localVarRequest) + } + + // Basic HTTP Authentication + if auth, ok := ctx.Value(ContextBasicAuth).(BasicAuth); ok { + localVarRequest.SetBasicAuth(auth.UserName, auth.Password) + } + + // AccessToken Authentication + if auth, ok := ctx.Value(ContextAccessToken).(string); ok { + localVarRequest.Header.Add("Authorization", "Bearer "+auth) + } + } + + for header, value := range c.cfg.DefaultHeader { + localVarRequest.Header.Add(header, value) + } + return localVarRequest, nil +} + +func (c *APIClient) decode(v interface{}, b []byte, contentType string) (err error) { + if len(b) == 0 { + return nil + } + if s, ok := v.(*string); ok { + *s = string(b) + return nil + } + if xmlCheck.MatchString(contentType) { + if err = xml.Unmarshal(b, v); err != nil { + return err + } + return nil + } + if jsonCheck.MatchString(contentType) { + if actualObj, ok := v.(interface{ GetActualInstance() interface{} }); ok { // oneOf, anyOf schemas + if unmarshalObj, ok := actualObj.(interface{ UnmarshalJSON([]byte) error }); ok { // make sure it has UnmarshalJSON defined + if err = unmarshalObj.UnmarshalJSON(b); err != nil { + return err + } + } else { + errors.New("Unknown type with GetActualInstance but no unmarshalObj.UnmarshalJSON defined") + } + } else if err = json.Unmarshal(b, v); err != nil { // simple model + return err + } + return nil + } + return errors.New("undefined response type") +} + +// Add a file to the multipart request +func addFile(w *multipart.Writer, fieldName, path string) error { + file, err := os.Open(path) + if err != nil { + return err + } + defer file.Close() + + part, err := w.CreateFormFile(fieldName, filepath.Base(path)) + if err != nil { + return err + } + _, err = io.Copy(part, file) + + return err +} + +// Prevent trying to import "fmt" +func reportError(format string, a ...interface{}) error { + return fmt.Errorf(format, a...) +} + +// Set request body from an interface{} +func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err error) { + if bodyBuf == nil { + bodyBuf = &bytes.Buffer{} + } + + if reader, ok := body.(io.Reader); ok { + _, err = bodyBuf.ReadFrom(reader) + } else if b, ok := body.([]byte); ok { + _, err = bodyBuf.Write(b) + } else if s, ok := body.(string); ok { + _, err = bodyBuf.WriteString(s) + } else if s, ok := body.(*string); ok { + _, err = bodyBuf.WriteString(*s) + } else if jsonCheck.MatchString(contentType) { + err = json.NewEncoder(bodyBuf).Encode(body) + } else if xmlCheck.MatchString(contentType) { + err = xml.NewEncoder(bodyBuf).Encode(body) + } + + if err != nil { + return nil, err + } + + if bodyBuf.Len() == 0 { + err = fmt.Errorf("Invalid body type %s\n", contentType) + return nil, err + } + return bodyBuf, nil +} + +// detectContentType method is used to figure out `Request.Body` content type for request header +func detectContentType(body interface{}) string { + contentType := "text/plain; charset=utf-8" + kind := reflect.TypeOf(body).Kind() + + switch kind { + case reflect.Struct, reflect.Map, reflect.Ptr: + contentType = "application/json; charset=utf-8" + case reflect.String: + contentType = "text/plain; charset=utf-8" + default: + if b, ok := body.([]byte); ok { + contentType = http.DetectContentType(b) + } else if kind == reflect.Slice { + contentType = "application/json; charset=utf-8" + } + } + + return contentType +} + +// Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go +type cacheControl map[string]string + +func parseCacheControl(headers http.Header) cacheControl { + cc := cacheControl{} + ccHeader := headers.Get("Cache-Control") + for _, part := range strings.Split(ccHeader, ",") { + part = strings.Trim(part, " ") + if part == "" { + continue + } + if strings.ContainsRune(part, '=') { + keyval := strings.Split(part, "=") + cc[strings.Trim(keyval[0], " ")] = strings.Trim(keyval[1], ",") + } else { + cc[part] = "" + } + } + return cc +} + +// CacheExpires helper function to determine remaining time before repeating a request. +func CacheExpires(r *http.Response) time.Time { + // Figure out when the cache expires. + var expires time.Time + now, err := time.Parse(time.RFC1123, r.Header.Get("date")) + if err != nil { + return time.Now() + } + respCacheControl := parseCacheControl(r.Header) + + if maxAge, ok := respCacheControl["max-age"]; ok { + lifetime, err := time.ParseDuration(maxAge + "s") + if err != nil { + expires = now + } else { + expires = now.Add(lifetime) + } + } else { + expiresHeader := r.Header.Get("Expires") + if expiresHeader != "" { + expires, err = time.Parse(time.RFC1123, expiresHeader) + if err != nil { + expires = now + } + } + } + return expires +} + +func strlen(s string) int { + return utf8.RuneCountInString(s) +} + +// GenericOpenAPIError Provides access to the body, error and model on returned errors. +type GenericOpenAPIError struct { + body []byte + error string + model interface{} +} + +// Error returns non-empty string if there was an error. +func (e GenericOpenAPIError) Error() string { + return e.error +} + +// Body returns the raw bytes of the response +func (e GenericOpenAPIError) Body() []byte { + return e.body +} + +// Model returns the unpacked model of the error +func (e GenericOpenAPIError) Model() interface{} { + return e.model +} diff --git a/pinning/remote/client/openapi/configuration.go b/pinning/remote/client/openapi/configuration.go new file mode 100644 index 000000000..2dd763a9d --- /dev/null +++ b/pinning/remote/client/openapi/configuration.go @@ -0,0 +1,228 @@ +/* + * IPFS Pinning Service API + * + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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.0.5 + * 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) +} diff --git a/pinning/remote/client/openapi/docs/Error.md b/pinning/remote/client/openapi/docs/Error.md new file mode 100644 index 000000000..e88553965 --- /dev/null +++ b/pinning/remote/client/openapi/docs/Error.md @@ -0,0 +1,72 @@ +# Error + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Code** | **int32** | | +**Message** | **string** | | + +## Methods + +### NewError + +`func NewError(code int32, message string, ) *Error` + +NewError instantiates a new Error 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 + +### NewErrorWithDefaults + +`func NewErrorWithDefaults() *Error` + +NewErrorWithDefaults instantiates a new Error 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 + +### GetCode + +`func (o *Error) GetCode() int32` + +GetCode returns the Code field if non-nil, zero value otherwise. + +### GetCodeOk + +`func (o *Error) GetCodeOk() (*int32, bool)` + +GetCodeOk returns a tuple with the Code field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetCode + +`func (o *Error) SetCode(v int32)` + +SetCode sets Code field to given value. + + +### GetMessage + +`func (o *Error) GetMessage() string` + +GetMessage returns the Message field if non-nil, zero value otherwise. + +### GetMessageOk + +`func (o *Error) GetMessageOk() (*string, bool)` + +GetMessageOk returns a tuple with the Message field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetMessage + +`func (o *Error) SetMessage(v string)` + +SetMessage sets Message 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) + + diff --git a/pinning/remote/client/openapi/docs/Pin.md b/pinning/remote/client/openapi/docs/Pin.md new file mode 100644 index 000000000..cbdf1a0b7 --- /dev/null +++ b/pinning/remote/client/openapi/docs/Pin.md @@ -0,0 +1,129 @@ +# Pin + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Cid** | **string** | 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) + + diff --git a/pinning/remote/client/openapi/docs/PinResults.md b/pinning/remote/client/openapi/docs/PinResults.md new file mode 100644 index 000000000..1982bfddb --- /dev/null +++ b/pinning/remote/client/openapi/docs/PinResults.md @@ -0,0 +1,72 @@ +# 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) + + diff --git a/pinning/remote/client/openapi/docs/PinStatus.md b/pinning/remote/client/openapi/docs/PinStatus.md new file mode 100644 index 000000000..2408abfda --- /dev/null +++ b/pinning/remote/client/openapi/docs/PinStatus.md @@ -0,0 +1,161 @@ +# PinStatus + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Id** | **string** | Globally unique ID of the pin request; can be used to check the status of ongoing pinning, modification of pin object, 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(id 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 + +### GetId + +`func (o *PinStatus) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *PinStatus) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *PinStatus) SetId(v string)` + +SetId sets Id 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) + + diff --git a/pinning/remote/client/openapi/docs/PinsApi.md b/pinning/remote/client/openapi/docs/PinsApi.md new file mode 100644 index 000000000..0aea62d99 --- /dev/null +++ b/pinning/remote/client/openapi/docs/PinsApi.md @@ -0,0 +1,367 @@ +# \PinsApi + +All URIs are relative to *https://pinning-service.example.com* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**PinsGet**](PinsApi.md#PinsGet) | **Get** /pins | List pin objects +[**PinsIdDelete**](PinsApi.md#PinsIdDelete) | **Delete** /pins/{id} | Remove pin object +[**PinsIdGet**](PinsApi.md#PinsIdGet) | **Get** /pins/{id} | Get pin object +[**PinsIdPost**](PinsApi.md#PinsIdPost) | **Post** /pins/{id} | Modify pin object +[**PinsPost**](PinsApi.md#PinsPost) | **Post** /pins | Add 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) (optional) + name := "name_example" // string | Return pin objects with names that contain provided value (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) | + **name** | **string** | Return pin objects with names that contain provided value (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) + + +## PinsIdDelete + +> PinsIdDelete(ctx, id).Execute() + +Remove pin object + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "./openapi" +) + +func main() { + id := "id_example" // string | + + configuration := openapiclient.NewConfiguration() + api_client := openapiclient.NewAPIClient(configuration) + resp, r, err := api_client.PinsApi.PinsIdDelete(context.Background(), id).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `PinsApi.PinsIdDelete``: %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. +**id** | **string** | | + +### Other Parameters + +Other parameters are passed through a pointer to a apiPinsIdDeleteRequest 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) + + +## PinsIdGet + +> PinStatus PinsIdGet(ctx, id).Execute() + +Get pin object + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "./openapi" +) + +func main() { + id := "id_example" // string | + + configuration := openapiclient.NewConfiguration() + api_client := openapiclient.NewAPIClient(configuration) + resp, r, err := api_client.PinsApi.PinsIdGet(context.Background(), id).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `PinsApi.PinsIdGet``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `PinsIdGet`: PinStatus + fmt.Fprintf(os.Stdout, "Response from `PinsApi.PinsIdGet`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | | + +### Other Parameters + +Other parameters are passed through a pointer to a apiPinsIdGetRequest 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) + + +## PinsIdPost + +> PinStatus PinsIdPost(ctx, id).Pin(pin).Execute() + +Modify pin object + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "./openapi" +) + +func main() { + id := "id_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.PinsIdPost(context.Background(), id, pin).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `PinsApi.PinsIdPost``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `PinsIdPost`: PinStatus + fmt.Fprintf(os.Stdout, "Response from `PinsApi.PinsIdPost`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**id** | **string** | | + +### Other Parameters + +Other parameters are passed through a pointer to a apiPinsIdPostRequest 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) + + +## 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) + diff --git a/pinning/remote/client/openapi/docs/Status.md b/pinning/remote/client/openapi/docs/Status.md new file mode 100644 index 000000000..01176af11 --- /dev/null +++ b/pinning/remote/client/openapi/docs/Status.md @@ -0,0 +1,11 @@ +# 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) + + diff --git a/pinning/remote/client/openapi/model_error.go b/pinning/remote/client/openapi/model_error.go new file mode 100644 index 000000000..d97ecaa2c --- /dev/null +++ b/pinning/remote/client/openapi/model_error.go @@ -0,0 +1,134 @@ +/* + * IPFS Pinning Service API + * + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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.0.5 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "encoding/json" +) + +// Error Base error object +type Error struct { + Code int32 `json:"code"` + Message string `json:"message"` +} + +// NewError instantiates a new Error 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 NewError(code int32, message string) *Error { + this := Error{} + this.Code = code + this.Message = message + return &this +} + +// NewErrorWithDefaults instantiates a new Error 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 NewErrorWithDefaults() *Error { + this := Error{} + return &this +} + +// GetCode returns the Code field value +func (o *Error) GetCode() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Code +} + +// GetCodeOk returns a tuple with the Code field value +// and a boolean to check if the value has been set. +func (o *Error) GetCodeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Code, true +} + +// SetCode sets field value +func (o *Error) SetCode(v int32) { + o.Code = v +} + +// GetMessage returns the Message field value +func (o *Error) GetMessage() string { + if o == nil { + var ret string + return ret + } + + return o.Message +} + +// GetMessageOk returns a tuple with the Message field value +// and a boolean to check if the value has been set. +func (o *Error) GetMessageOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Message, true +} + +// SetMessage sets field value +func (o *Error) SetMessage(v string) { + o.Message = v +} + +func (o Error) MarshalJSON() ([]byte, error) { + toSerialize := map[string]interface{}{} + if true { + toSerialize["code"] = o.Code + } + if true { + toSerialize["message"] = o.Message + } + return json.Marshal(toSerialize) +} + +type NullableError struct { + value *Error + isSet bool +} + +func (v NullableError) Get() *Error { + return v.value +} + +func (v *NullableError) Set(val *Error) { + v.value = val + v.isSet = true +} + +func (v NullableError) IsSet() bool { + return v.isSet +} + +func (v *NullableError) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableError(val *Error) *NullableError { + return &NullableError{value: val, isSet: true} +} + +func (v NullableError) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableError) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pinning/remote/client/openapi/model_pin.go b/pinning/remote/client/openapi/model_pin.go new file mode 100644 index 000000000..c4a5e8015 --- /dev/null +++ b/pinning/remote/client/openapi/model_pin.go @@ -0,0 +1,217 @@ +/* + * IPFS Pinning Service API + * + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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.0.5 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "encoding/json" +) + +// Pin Pin object +type Pin struct { + // 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) +} diff --git a/pinning/remote/client/openapi/model_pin_results.go b/pinning/remote/client/openapi/model_pin_results.go new file mode 100644 index 000000000..ac8443976 --- /dev/null +++ b/pinning/remote/client/openapi/model_pin_results.go @@ -0,0 +1,136 @@ +/* + * IPFS Pinning Service API + * + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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.0.5 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "encoding/json" +) + +// PinResults Response used for listing pin objects matching request +type PinResults struct { + // The total number of pin objects that exist for passed query filters + Count int32 `json:"count"` + // An array of PinStatus results + Results []PinStatus `json:"results"` +} + +// 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 +func NewPinResults(count int32, results []PinStatus) *PinResults { + this := PinResults{} + this.Count = count + this.Results = results + return &this +} + +// 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 +func NewPinResultsWithDefaults() *PinResults { + this := PinResults{} + return &this +} + +// GetCount returns the Count field value +func (o *PinResults) GetCount() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Count +} + +// GetCountOk returns a tuple with the Count field value +// and a boolean to check if the value has been set. +func (o *PinResults) GetCountOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Count, true +} + +// SetCount sets field value +func (o *PinResults) SetCount(v int32) { + o.Count = v +} + +// GetResults returns the Results field value +func (o *PinResults) GetResults() []PinStatus { + if o == nil { + var ret []PinStatus + return ret + } + + return o.Results +} + +// GetResultsOk returns a tuple with the Results field value +// and a boolean to check if the value has been set. +func (o *PinResults) GetResultsOk() (*[]PinStatus, bool) { + if o == nil { + return nil, false + } + return &o.Results, true +} + +// SetResults sets field value +func (o *PinResults) SetResults(v []PinStatus) { + o.Results = v +} + +func (o PinResults) MarshalJSON() ([]byte, error) { + toSerialize := map[string]interface{}{} + if true { + toSerialize["count"] = o.Count + } + if true { + toSerialize["results"] = o.Results + } + return json.Marshal(toSerialize) +} + +type NullablePinResults struct { + value *PinResults + isSet bool +} + +func (v NullablePinResults) Get() *PinResults { + return v.value +} + +func (v *NullablePinResults) Set(val *PinResults) { + v.value = val + v.isSet = true +} + +func (v NullablePinResults) IsSet() bool { + return v.isSet +} + +func (v *NullablePinResults) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullablePinResults(val *PinResults) *NullablePinResults { + return &NullablePinResults{value: val, isSet: true} +} + +func (v NullablePinResults) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullablePinResults) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pinning/remote/client/openapi/model_pin_status.go b/pinning/remote/client/openapi/model_pin_status.go new file mode 100644 index 000000000..78f37dcd2 --- /dev/null +++ b/pinning/remote/client/openapi/model_pin_status.go @@ -0,0 +1,262 @@ +/* + * IPFS Pinning Service API + * + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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.0.5 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "encoding/json" + "time" +) + +// PinStatus Pin object with status +type PinStatus struct { + // Globally unique ID of the pin request; can be used to check the status of ongoing pinning, modification of pin object, or pin removal + Id string `json:"id"` + Status Status `json:"status"` + // Immutable timestamp indicating when a pin request entered a pinning service; can be used for filtering results and pagination + Created time.Time `json:"created"` + Pin Pin `json:"pin"` + // List of multiaddrs designated by pinning service for transferring any new data from external peers + Delegates []string `json:"delegates"` + // Optional info for PinStatus response + Info *map[string]string `json:"info,omitempty"` +} + +// 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 +func NewPinStatus(id string, status Status, created time.Time, pin Pin, delegates []string) *PinStatus { + this := PinStatus{} + this.Id = id + this.Status = status + this.Created = created + this.Pin = pin + this.Delegates = delegates + return &this +} + +// 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 +func NewPinStatusWithDefaults() *PinStatus { + this := PinStatus{} + return &this +} + +// GetId returns the Id field value +func (o *PinStatus) GetId() string { + if o == nil { + var ret string + return ret + } + + return o.Id +} + +// GetIdOk returns a tuple with the Id field value +// and a boolean to check if the value has been set. +func (o *PinStatus) GetIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Id, true +} + +// SetId sets field value +func (o *PinStatus) SetId(v string) { + o.Id = v +} + +// GetStatus returns the Status field value +func (o *PinStatus) GetStatus() Status { + if o == nil { + var ret Status + return ret + } + + return o.Status +} + +// GetStatusOk returns a tuple with the Status field value +// and a boolean to check if the value has been set. +func (o *PinStatus) GetStatusOk() (*Status, bool) { + if o == nil { + return nil, false + } + return &o.Status, true +} + +// SetStatus sets field value +func (o *PinStatus) SetStatus(v Status) { + o.Status = v +} + +// GetCreated returns the Created field value +func (o *PinStatus) GetCreated() time.Time { + if o == nil { + var ret time.Time + return ret + } + + return o.Created +} + +// GetCreatedOk returns a tuple with the Created field value +// and a boolean to check if the value has been set. +func (o *PinStatus) GetCreatedOk() (*time.Time, bool) { + if o == nil { + return nil, false + } + return &o.Created, true +} + +// SetCreated sets field value +func (o *PinStatus) SetCreated(v time.Time) { + o.Created = v +} + +// GetPin returns the Pin field value +func (o *PinStatus) GetPin() Pin { + if o == nil { + var ret Pin + return ret + } + + return o.Pin +} + +// GetPinOk returns a tuple with the Pin field value +// and a boolean to check if the value has been set. +func (o *PinStatus) GetPinOk() (*Pin, bool) { + if o == nil { + return nil, false + } + return &o.Pin, true +} + +// SetPin sets field value +func (o *PinStatus) SetPin(v Pin) { + o.Pin = v +} + +// GetDelegates returns the Delegates field value +func (o *PinStatus) GetDelegates() []string { + if o == nil { + var ret []string + return ret + } + + return o.Delegates +} + +// GetDelegatesOk returns a tuple with the Delegates field value +// and a boolean to check if the value has been set. +func (o *PinStatus) GetDelegatesOk() (*[]string, bool) { + if o == nil { + return nil, false + } + return &o.Delegates, true +} + +// SetDelegates sets field value +func (o *PinStatus) SetDelegates(v []string) { + o.Delegates = v +} + +// GetInfo returns the Info field value if set, zero value otherwise. +func (o *PinStatus) GetInfo() map[string]string { + if o == nil || o.Info == nil { + var ret map[string]string + return ret + } + return *o.Info +} + +// GetInfoOk returns a tuple with the Info field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *PinStatus) GetInfoOk() (*map[string]string, bool) { + if o == nil || o.Info == nil { + return nil, false + } + return o.Info, true +} + +// HasInfo returns a boolean if a field has been set. +func (o *PinStatus) HasInfo() bool { + if o != nil && o.Info != nil { + return true + } + + return false +} + +// SetInfo gets a reference to the given map[string]string and assigns it to the Info field. +func (o *PinStatus) SetInfo(v map[string]string) { + o.Info = &v +} + +func (o PinStatus) MarshalJSON() ([]byte, error) { + toSerialize := map[string]interface{}{} + if true { + toSerialize["id"] = o.Id + } + if true { + toSerialize["status"] = o.Status + } + if true { + toSerialize["created"] = o.Created + } + if true { + toSerialize["pin"] = o.Pin + } + if true { + toSerialize["delegates"] = o.Delegates + } + if o.Info != nil { + toSerialize["info"] = o.Info + } + return json.Marshal(toSerialize) +} + +type NullablePinStatus struct { + value *PinStatus + isSet bool +} + +func (v NullablePinStatus) Get() *PinStatus { + return v.value +} + +func (v *NullablePinStatus) Set(val *PinStatus) { + v.value = val + v.isSet = true +} + +func (v NullablePinStatus) IsSet() bool { + return v.isSet +} + +func (v *NullablePinStatus) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullablePinStatus(val *PinStatus) *NullablePinStatus { + return &NullablePinStatus{value: val, isSet: true} +} + +func (v NullablePinStatus) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullablePinStatus) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pinning/remote/client/openapi/model_status.go b/pinning/remote/client/openapi/model_status.go new file mode 100644 index 000000000..fe727407e --- /dev/null +++ b/pinning/remote/client/openapi/model_status.go @@ -0,0 +1,84 @@ +/* + * IPFS Pinning Service API + * + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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.0.5 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "encoding/json" + "fmt" +) + +// Status Status a pin object can have at a pinning service +type Status string + +// List of Status +const ( + QUEUED Status = "queued" + PINNING Status = "pinning" + PINNED Status = "pinned" + FAILED Status = "failed" +) + +func (v *Status) UnmarshalJSON(src []byte) error { + var value string + err := json.Unmarshal(src, &value) + if err != nil { + return err + } + enumTypeValue := Status(value) + for _, existing := range []Status{"queued", "pinning", "pinned", "failed"} { + if existing == enumTypeValue { + *v = enumTypeValue + return nil + } + } + + return fmt.Errorf("%+v is not a valid Status", value) +} + +// Ptr returns reference to Status value +func (v Status) Ptr() *Status { + return &v +} + +type NullableStatus struct { + value *Status + isSet bool +} + +func (v NullableStatus) Get() *Status { + return v.value +} + +func (v *NullableStatus) Set(val *Status) { + v.value = val + v.isSet = true +} + +func (v NullableStatus) IsSet() bool { + return v.isSet +} + +func (v *NullableStatus) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableStatus(val *Status) *NullableStatus { + return &NullableStatus{value: val, isSet: true} +} + +func (v NullableStatus) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableStatus) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pinning/remote/client/openapi/response.go b/pinning/remote/client/openapi/response.go new file mode 100644 index 000000000..d053bb91f --- /dev/null +++ b/pinning/remote/client/openapi/response.go @@ -0,0 +1,46 @@ +/* + * IPFS Pinning Service API + * + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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.0.5 + * 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 +} diff --git a/pinning/remote/client/openapi/utils.go b/pinning/remote/client/openapi/utils.go new file mode 100644 index 000000000..a5daa9247 --- /dev/null +++ b/pinning/remote/client/openapi/utils.go @@ -0,0 +1,327 @@ +/* + * IPFS Pinning Service API + * + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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.0.5 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "encoding/json" + "time" +) + +// PtrBool is a helper routine that returns a pointer to given integer value. +func PtrBool(v bool) *bool { return &v } + +// PtrInt is a helper routine that returns a pointer to given integer value. +func PtrInt(v int) *int { return &v } + +// PtrInt32 is a helper routine that returns a pointer to given integer value. +func PtrInt32(v int32) *int32 { return &v } + +// PtrInt64 is a helper routine that returns a pointer to given integer value. +func PtrInt64(v int64) *int64 { return &v } + +// PtrFloat32 is a helper routine that returns a pointer to given float value. +func PtrFloat32(v float32) *float32 { return &v } + +// PtrFloat64 is a helper routine that returns a pointer to given float value. +func PtrFloat64(v float64) *float64 { return &v } + +// PtrString is a helper routine that returns a pointer to given string value. +func PtrString(v string) *string { return &v } + +// PtrTime is helper routine that returns a pointer to given Time value. +func PtrTime(v time.Time) *time.Time { return &v } + +type NullableBool struct { + value *bool + isSet bool +} + +func (v NullableBool) Get() *bool { + return v.value +} + +func (v *NullableBool) Set(val *bool) { + v.value = val + v.isSet = true +} + +func (v NullableBool) IsSet() bool { + return v.isSet +} + +func (v *NullableBool) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableBool(val *bool) *NullableBool { + return &NullableBool{value: val, isSet: true} +} + +func (v NullableBool) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableBool) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableInt struct { + value *int + isSet bool +} + +func (v NullableInt) Get() *int { + return v.value +} + +func (v *NullableInt) Set(val *int) { + v.value = val + v.isSet = true +} + +func (v NullableInt) IsSet() bool { + return v.isSet +} + +func (v *NullableInt) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableInt(val *int) *NullableInt { + return &NullableInt{value: val, isSet: true} +} + +func (v NullableInt) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableInt) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableInt32 struct { + value *int32 + isSet bool +} + +func (v NullableInt32) Get() *int32 { + return v.value +} + +func (v *NullableInt32) Set(val *int32) { + v.value = val + v.isSet = true +} + +func (v NullableInt32) IsSet() bool { + return v.isSet +} + +func (v *NullableInt32) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableInt32(val *int32) *NullableInt32 { + return &NullableInt32{value: val, isSet: true} +} + +func (v NullableInt32) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableInt32) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableInt64 struct { + value *int64 + isSet bool +} + +func (v NullableInt64) Get() *int64 { + return v.value +} + +func (v *NullableInt64) Set(val *int64) { + v.value = val + v.isSet = true +} + +func (v NullableInt64) IsSet() bool { + return v.isSet +} + +func (v *NullableInt64) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableInt64(val *int64) *NullableInt64 { + return &NullableInt64{value: val, isSet: true} +} + +func (v NullableInt64) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableInt64) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableFloat32 struct { + value *float32 + isSet bool +} + +func (v NullableFloat32) Get() *float32 { + return v.value +} + +func (v *NullableFloat32) Set(val *float32) { + v.value = val + v.isSet = true +} + +func (v NullableFloat32) IsSet() bool { + return v.isSet +} + +func (v *NullableFloat32) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableFloat32(val *float32) *NullableFloat32 { + return &NullableFloat32{value: val, isSet: true} +} + +func (v NullableFloat32) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableFloat32) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableFloat64 struct { + value *float64 + isSet bool +} + +func (v NullableFloat64) Get() *float64 { + return v.value +} + +func (v *NullableFloat64) Set(val *float64) { + v.value = val + v.isSet = true +} + +func (v NullableFloat64) IsSet() bool { + return v.isSet +} + +func (v *NullableFloat64) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableFloat64(val *float64) *NullableFloat64 { + return &NullableFloat64{value: val, isSet: true} +} + +func (v NullableFloat64) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableFloat64) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableString struct { + value *string + isSet bool +} + +func (v NullableString) Get() *string { + return v.value +} + +func (v *NullableString) Set(val *string) { + v.value = val + v.isSet = true +} + +func (v NullableString) IsSet() bool { + return v.isSet +} + +func (v *NullableString) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableString(val *string) *NullableString { + return &NullableString{value: val, isSet: true} +} + +func (v NullableString) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableString) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableTime struct { + value *time.Time + isSet bool +} + +func (v NullableTime) Get() *time.Time { + return v.value +} + +func (v *NullableTime) Set(val *time.Time) { + v.value = val + v.isSet = true +} + +func (v NullableTime) IsSet() bool { + return v.isSet +} + +func (v *NullableTime) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableTime(val *time.Time) *NullableTime { + return &NullableTime{value: val, isSet: true} +} + +func (v NullableTime) MarshalJSON() ([]byte, error) { + return v.value.MarshalJSON() +} + +func (v *NullableTime) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} From 5d1534a2cdaf586b92c1531a2dfe8481e2fc39d3 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Tue, 1 Sep 2020 13:12:49 -0400 Subject: [PATCH 3/8] better error logging/debugging + fixed ls bug This commit was moved from ipfs/go-pinning-service-http-client@fa6705a12566cb930bd7e1ef9e7f3ac57dca7f7a --- pinning/remote/client/client.go | 61 +++++++++++++++----- pinning/remote/client/cmd/main.go | 50 +++++++++++------ pinning/remote/client/model.go | 93 +++++++++++++++++++++++++++++-- 3 files changed, 167 insertions(+), 37 deletions(-) diff --git a/pinning/remote/client/client.go b/pinning/remote/client/client.go index b4fa37830..9a0043d7c 100644 --- a/pinning/remote/client/client.go +++ b/pinning/remote/client/client.go @@ -1,9 +1,10 @@ package go_pinning_service_http_client import ( + "bytes" "context" + "encoding/json" "fmt" - "io/ioutil" "net/http" "time" @@ -202,27 +203,31 @@ func (c *Client) LsSync(ctx context.Context, opts ...LsOption) ([]PinStatusGette func (c *Client) lsInternal(ctx context.Context, settings *lsSettings) (pinResults, error) { getter := c.client.PinsApi.PinsGet(ctx) if len(settings.cids) > 0 { - getter.Cid(settings.cids) + getter = getter.Cid(settings.cids) } if len(settings.status) > 0 { - getter.Status(settings.status) + 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.Limit(defaultLimit) + getter = getter.Limit(defaultLimit) } else { - getter.Limit(*settings.limit) + getter = getter.Limit(*settings.limit) } if len(settings.name) > 0 { - getter.Name(settings.name) + getter = getter.Name(settings.name) } if settings.before != nil { - getter.Before(*settings.before) + getter = getter.Before(*settings.before) } if settings.after != nil { - getter.After(*settings.after) + getter = getter.After(*settings.after) } if settings.meta != nil { - getter.Meta(settings.meta) + getter = getter.Meta(settings.meta) } // TODO: Ignoring HTTP Response OK? @@ -367,10 +372,38 @@ func getCIDEncoder() multibase.Encoder { } func httperr(resp *http.Response, e error) error { - body, err := ioutil.ReadAll(resp.Body) - var bodystr string - if err == nil { - bodystr = string(body) + oerr, ok := e.(openapi.GenericOpenAPIError) + if !ok { + panic("wrong error type") + } + var buf bytes.Buffer + var err error + + var reqStr string + if resp.Request.GetBody != nil { + resp.Request.Body, err = resp.Request.GetBody() + if err != nil { + reqStr = err.Error() + } else if err := resp.Request.Write(&buf); err != nil { + reqStr = err.Error() + } else { + reqStr = buf.String() + } + } else { + reqStr = resp.Request.URL.String() } - return fmt.Errorf("httpresp code: %d, httpresp: %s, httpbody: %s, err: %w", resp.StatusCode, resp.Status, bodystr, e) + + bodystr := string(oerr.Body()) + //body, err := ioutil.ReadAll(resp.Body) + //var bodystr string + //if err == nil { + // bodystr = string(body) + //} + relevantErr := fmt.Sprintf("{ httpcode: %d, httpresp: %s, httpbody: %s, reqstr: %s }", resp.StatusCode, resp.Status, bodystr, reqStr) + relevantErrBytes, err := json.MarshalIndent(relevantErr, "", "\t") + if err != nil { + return fmt.Errorf("RelevantInfo : %s, MarshalErr: %w, Err: %w", relevantErr, err, e) + } + + return fmt.Errorf("relevantErr: %s, err: %w", relevantErrBytes, e) } diff --git a/pinning/remote/client/cmd/main.go b/pinning/remote/client/cmd/main.go index fefd9503d..d5b74bb2f 100644 --- a/pinning/remote/client/cmd/main.go +++ b/pinning/remote/client/cmd/main.go @@ -6,6 +6,7 @@ import ( "github.com/ipfs/go-cid" pinclient "github.com/ipfs/go-pinning-service-http-client" "os" + "time" ) func main() { @@ -35,30 +36,37 @@ func main() { } _ = ipfsPgCid + listPins(ctx, c) + fmt.Println("Adding libp2p home page") - ps, err := c.Add(ctx, libp2pCid, pinclient.PinOpts.WithName("libp2p_home")) + ps, err := c.Add(ctx, libp2pCid, pinclient.PinOpts.WithName("libp2p")) if err == nil { - fmt.Println(ps.GetStatus()) + fmt.Printf("PinStatus: %v \n", ps) } else { fmt.Println(err) } - fmt.Println("List all pins") - pins, err := c.LsSync(ctx) - fmt.Println(err) + listPins(ctx, c) - for _, p := range pins { - fmt.Printf("Pin Name: %s, CID: %s", p.GetPin().GetName(), p.GetPin().GetCid().String()) + fmt.Println("Check on pin status") + if ps == nil { + panic("Skipping pin status check because the pin is null") } - fmt.Println("Check on pin status") - status, err := c.GetStatusByID(ctx, ps.GetId()) - if err == nil { - fmt.Println(status.GetStatus()) - } else { - fmt.Println(err) + var pinned bool + for !pinned { + status, err := c.GetStatusByID(ctx, ps.GetId()) + 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.GetId()) if err == nil { @@ -67,11 +75,17 @@ func main() { fmt.Println(err) } - fmt.Println("List all pins") - pins, err = c.LsSync(ctx) - fmt.Println(err) + listPins(ctx, c) +} - for _, p := range pins { - fmt.Printf("Pin Name: %s, CID: %s", p.GetPin().GetName(), p.GetPin().GetCid().String()) +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) + } } } diff --git a/pinning/remote/client/model.go b/pinning/remote/client/model.go index e6c552d51..cbb4eaeb1 100644 --- a/pinning/remote/client/model.go +++ b/pinning/remote/client/model.go @@ -1,6 +1,8 @@ package go_pinning_service_http_client import ( + "encoding/json" + "fmt" "github.com/ipfs/go-cid" "github.com/ipfs/go-pinning-service-http-client/openapi" "github.com/multiformats/go-multiaddr" @@ -9,6 +11,8 @@ import ( // 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 @@ -23,6 +27,37 @@ 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) + } + } + + var metaStr string + 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 { @@ -31,19 +66,31 @@ func (p *pinObject) GetCid() cid.Cid { return c } -type Status = openapi.Status +type Status string const ( - StatusQueued Status = openapi.QUEUED - StatusPinning Status = openapi.PINNING - StatusPinned Status = openapi.PINNED - StatusFailed Status = openapi.FAILED + 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 GetId() string GetStatus() Status @@ -77,3 +124,39 @@ func (p *pinStatusObject) GetDelegates() []multiaddr.Multiaddr { func (p *pinStatusObject) GetPin() PinGetter { return &pinObject{p.Pin} } + +func (p *pinStatusObject) GetStatus() Status { + return Status(p.PinStatus.GetStatus()) +} + +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) + } + } + + var infoStr string + if info := p.GetInfo(); info != nil { + infoBytes, err := json.Marshal(info) + if err == nil { + infoStr = string(infoBytes) + } + } + + str := fmt.Sprintf("{\"Pin\" : %v, \"ID\" : \"%s\", \"Status\" : \"%s\", \"Created\" : \"%v\", \"Delegates\" : %v, \"Info\" : %v }", + p.GetPin(), p.GetId(), 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) +} From cc34a8bfe3877861ee954cc98428ff83d98dd60b Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 10 Sep 2020 21:26:38 -0400 Subject: [PATCH 4/8] fix: properly emit JSON strings for empty maps in pin and pinStatus objects This commit was moved from ipfs/go-pinning-service-http-client@c86fa75aedfb020006ae17b2f49d6eb8842cb6b9 --- pinning/remote/client/model.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pinning/remote/client/model.go b/pinning/remote/client/model.go index cbb4eaeb1..8fb51efff 100644 --- a/pinning/remote/client/model.go +++ b/pinning/remote/client/model.go @@ -36,7 +36,7 @@ func (p *pinObject) MarshalJSON() ([]byte, error) { } } - var metaStr string + metaStr := "{}" if meta := p.GetMeta(); meta != nil { metaBytes, err := json.Marshal(meta) if err == nil { @@ -138,7 +138,7 @@ func (p *pinStatusObject) MarshalJSON() ([]byte, error) { } } - var infoStr string + infoStr := "{}" if info := p.GetInfo(); info != nil { infoBytes, err := json.Marshal(info) if err == nil { From bc509bd0c0a1d94b3664a5637568d3d01ab586cc Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Mon, 21 Sep 2020 16:08:11 -0400 Subject: [PATCH 5/8] feat: update to pinning service api spec v1.0.0 This commit was moved from ipfs/go-pinning-service-http-client@0f15288be30ead28cf15b210e29fea521e1db8d7 --- pinning/remote/client/client.go | 11 +- pinning/remote/client/cmd/main.go | 4 +- pinning/remote/client/model.go | 10 +- pinning/remote/client/openapi/README.md | 36 +- pinning/remote/client/openapi/api_pins.go | 324 ++++++++++++------ pinning/remote/client/openapi/client.go | 2 +- .../remote/client/openapi/configuration.go | 2 +- pinning/remote/client/openapi/docs/Error.md | 43 +-- .../remote/client/openapi/docs/ErrorError.md | 77 +++++ pinning/remote/client/openapi/docs/Pin.md | 2 +- .../remote/client/openapi/docs/PinStatus.md | 22 +- pinning/remote/client/openapi/docs/PinsApi.md | 106 +++--- pinning/remote/client/openapi/model_error.go | 61 +--- .../client/openapi/model_error_error.go | 143 ++++++++ pinning/remote/client/openapi/model_pin.go | 4 +- .../client/openapi/model_pin_results.go | 2 +- .../remote/client/openapi/model_pin_status.go | 32 +- pinning/remote/client/openapi/model_status.go | 2 +- pinning/remote/client/openapi/response.go | 2 +- pinning/remote/client/openapi/utils.go | 2 +- 20 files changed, 592 insertions(+), 295 deletions(-) create mode 100644 pinning/remote/client/openapi/docs/ErrorError.md create mode 100644 pinning/remote/client/openapi/model_error_error.go diff --git a/pinning/remote/client/client.go b/pinning/remote/client/client.go index 9a0043d7c..f021abb08 100644 --- a/pinning/remote/client/client.go +++ b/pinning/remote/client/client.go @@ -39,7 +39,8 @@ func NewClient(url, bearerToken string) *Client { } func getError(e *openapi.Error) error { - return fmt.Errorf("request error: %d - %s", e.Code, e.Message) + err := e.GetError() + return fmt.Errorf("request error: %s - %s", err.GetReason(), err.GetDetails()) } // TODO: We should probably make sure there are no duplicates sent @@ -311,7 +312,7 @@ func (c *Client) Add(ctx context.Context, cid cid.Cid, opts ...AddOption) (PinSt } func (c *Client) GetStatusByID(ctx context.Context, pinID string) (PinStatusGetter, error) { - getter := c.client.PinsApi.PinsIdGet(ctx, pinID) + getter := c.client.PinsApi.PinsRequestidGet(ctx, pinID) result, httpresp, err := getter.Execute() if err != nil { err := httperr(httpresp, err) @@ -322,7 +323,7 @@ func (c *Client) GetStatusByID(ctx context.Context, pinID string) (PinStatusGett } func (c *Client) DeleteByID(ctx context.Context, pinID string) error { - deleter := c.client.PinsApi.PinsIdDelete(ctx, pinID) + deleter := c.client.PinsApi.PinsRequestidDelete(ctx, pinID) httpresp, err := deleter.Execute() if err != nil { err := httperr(httpresp, err) @@ -339,7 +340,7 @@ func (c *Client) Modify(ctx context.Context, pinID string, cid cid.Cid, opts ... } } - adder := c.client.PinsApi.PinsIdPost(ctx, pinID) + adder := c.client.PinsApi.PinsRequestidPost(ctx, pinID) p := openapi.Pin{ Cid: cid.Encode(getCIDEncoder()), } @@ -402,7 +403,7 @@ func httperr(resp *http.Response, e error) error { relevantErr := fmt.Sprintf("{ httpcode: %d, httpresp: %s, httpbody: %s, reqstr: %s }", resp.StatusCode, resp.Status, bodystr, reqStr) relevantErrBytes, err := json.MarshalIndent(relevantErr, "", "\t") if err != nil { - return fmt.Errorf("RelevantInfo : %s, MarshalErr: %w, Err: %w", relevantErr, err, e) + return fmt.Errorf("RelevantInfo : %s, MarshalErr: %s, Err: %w", relevantErr, err, e) } return fmt.Errorf("relevantErr: %s, err: %w", relevantErrBytes, e) diff --git a/pinning/remote/client/cmd/main.go b/pinning/remote/client/cmd/main.go index d5b74bb2f..c095ed08c 100644 --- a/pinning/remote/client/cmd/main.go +++ b/pinning/remote/client/cmd/main.go @@ -55,7 +55,7 @@ func main() { var pinned bool for !pinned { - status, err := c.GetStatusByID(ctx, ps.GetId()) + status, err := c.GetStatusByID(ctx, ps.GetRequestId()) if err == nil { fmt.Println(status.GetStatus()) pinned = status.GetStatus() == pinclient.StatusPinned @@ -68,7 +68,7 @@ func main() { listPins(ctx, c) fmt.Println("Delete pin") - err = c.DeleteByID(ctx, ps.GetId()) + err = c.DeleteByID(ctx, ps.GetRequestId()) if err == nil { fmt.Println("Successfully deleted pin") } else { diff --git a/pinning/remote/client/model.go b/pinning/remote/client/model.go index 8fb51efff..506c43ae3 100644 --- a/pinning/remote/client/model.go +++ b/pinning/remote/client/model.go @@ -92,7 +92,7 @@ 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 - GetId() string + 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 @@ -129,6 +129,10 @@ 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 { @@ -146,8 +150,8 @@ func (p *pinStatusObject) MarshalJSON() ([]byte, error) { } } - str := fmt.Sprintf("{\"Pin\" : %v, \"ID\" : \"%s\", \"Status\" : \"%s\", \"Created\" : \"%v\", \"Delegates\" : %v, \"Info\" : %v }", - p.GetPin(), p.GetId(), p.GetStatus(), p.GetCreated(), delegatesStr, infoStr) + 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 } diff --git a/pinning/remote/client/openapi/README.md b/pinning/remote/client/openapi/README.md index 64e843f88..277bbc39a 100644 --- a/pinning/remote/client/openapi/README.md +++ b/pinning/remote/client/openapi/README.md @@ -13,10 +13,21 @@ The IPFS Pinning Service API is intended to be an implementation-agnostic API&#x 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 -![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.png) +![pin object](https://bafybeideck2fchyxna4wqwc2mo67yriokehw3yujboc5redjdaajrk2fjq.ipfs.dweb.link/pin.png) The `Pin` object is a representation of a pin request. @@ -24,30 +35,30 @@ It includes the `cid` of data to be pinned, as well as optional metadata in `nam ### Pin status response -![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.png) +![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 `id` 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`. +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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) +![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: -- `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or removing the pin in the future +- `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/{id}` until pinning is successful, or the user decides to remove the pending pin. +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. -### Modifying an existing pin object -The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` is returned in the `PinStatus` response. The old pin object is deleted automatically. +### 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/{id}`. +A pin object can be removed via `DELETE /pins/{requestid}`. ## Provider hints @@ -161,15 +172,16 @@ 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* | [**PinsIdDelete**](docs/PinsApi.md#pinsiddelete) | **Delete** /pins/{id} | Remove pin object -*PinsApi* | [**PinsIdGet**](docs/PinsApi.md#pinsidget) | **Get** /pins/{id} | Get pin object -*PinsApi* | [**PinsIdPost**](docs/PinsApi.md#pinsidpost) | **Post** /pins/{id} | Modify pin object *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 - [Error](docs/Error.md) + - [ErrorError](docs/ErrorError.md) - [Pin](docs/Pin.md) - [PinResults](docs/PinResults.md) - [PinStatus](docs/PinStatus.md) diff --git a/pinning/remote/client/openapi/api_pins.go b/pinning/remote/client/openapi/api_pins.go index 623862df7..ff03d0c99 100644 --- a/pinning/remote/client/openapi/api_pins.go +++ b/pinning/remote/client/openapi/api_pins.go @@ -1,7 +1,7 @@ /* * IPFS Pinning Service API * - * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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. + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 * Generated by: OpenAPI Generator (https://openapi-generator.tech) @@ -180,7 +180,47 @@ func (r apiPinsGetRequest) Execute() (PinResults, *_nethttp.Response, error) { newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } - if localVarHTTPResponse.StatusCode == 500 { + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 409 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode > 400 && localVarHTTPResponse.StatusCode < 500 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode >= 500 { var v Error err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) if err != nil { @@ -204,54 +244,61 @@ func (r apiPinsGetRequest) Execute() (PinResults, *_nethttp.Response, error) { return localVarReturnValue, localVarHTTPResponse, nil } -type apiPinsIdDeleteRequest struct { +type apiPinsPostRequest struct { ctx _context.Context apiService *PinsApiService - id string + pin *Pin +} + +func (r apiPinsPostRequest) Pin(pin Pin) apiPinsPostRequest { + r.pin = &pin + return r } /* -PinsIdDelete Remove pin object -Remove a pin object +PinsPost Add pin object +Add a new pin object for the current access token * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - * @param id -@return apiPinsIdDeleteRequest +@return apiPinsPostRequest */ -func (a *PinsApiService) PinsIdDelete(ctx _context.Context, id string) apiPinsIdDeleteRequest { - return apiPinsIdDeleteRequest{ +func (a *PinsApiService) PinsPost(ctx _context.Context) apiPinsPostRequest { + return apiPinsPostRequest{ apiService: a, ctx: ctx, - id: id, } } /* Execute executes the request - + @return PinStatus */ -func (r apiPinsIdDeleteRequest) Execute() (*_nethttp.Response, error) { +func (r apiPinsPostRequest) Execute() (PinStatus, *_nethttp.Response, error) { var ( - localVarHTTPMethod = _nethttp.MethodDelete + localVarHTTPMethod = _nethttp.MethodPost localVarPostBody interface{} localVarFormFileName string localVarFileName string localVarFileBytes []byte + localVarReturnValue PinStatus ) - localBasePath, err := r.apiService.client.cfg.ServerURLWithContext(r.ctx, "PinsApiService.PinsIdDelete") + localBasePath, err := r.apiService.client.cfg.ServerURLWithContext(r.ctx, "PinsApiService.PinsPost") if err != nil { - return nil, GenericOpenAPIError{error: err.Error()} + return localVarReturnValue, nil, GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/pins/{id}" - localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", _neturl.PathEscape(parameterToString(r.id, "")), -1) + localVarPath := localBasePath + "/pins" localVarHeaderParams := make(map[string]string) localVarQueryParams := _neturl.Values{} localVarFormParams := _neturl.Values{} + if r.pin == nil { + return localVarReturnValue, nil, reportError("pin is required and must be specified") + } + // to determine the Content-Type header - localVarHTTPContentTypes := []string{} + localVarHTTPContentTypes := []string{"application/json"} // set Content-Type header localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) @@ -267,20 +314,22 @@ func (r apiPinsIdDeleteRequest) Execute() (*_nethttp.Response, error) { if localVarHTTPHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } + // body params + localVarPostBody = r.pin req, err := r.apiService.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes) if err != nil { - return nil, err + return localVarReturnValue, nil, err } localVarHTTPResponse, err := r.apiService.client.callAPI(req) if err != nil || localVarHTTPResponse == nil { - return localVarHTTPResponse, err + return localVarReturnValue, localVarHTTPResponse, err } localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body) localVarHTTPResponse.Body.Close() if err != nil { - return localVarHTTPResponse, err + return localVarReturnValue, localVarHTTPResponse, err } if localVarHTTPResponse.StatusCode >= 300 { @@ -293,88 +342,116 @@ func (r apiPinsIdDeleteRequest) Execute() (*_nethttp.Response, error) { err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) if err != nil { newErr.error = err.Error() - return localVarHTTPResponse, newErr + return localVarReturnValue, localVarHTTPResponse, newErr } newErr.model = v - return localVarHTTPResponse, newErr + return localVarReturnValue, localVarHTTPResponse, newErr } if localVarHTTPResponse.StatusCode == 401 { var v Error err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) if err != nil { newErr.error = err.Error() - return localVarHTTPResponse, newErr + return localVarReturnValue, localVarHTTPResponse, newErr } newErr.model = v - return localVarHTTPResponse, newErr + return localVarReturnValue, localVarHTTPResponse, newErr } if localVarHTTPResponse.StatusCode == 404 { var v Error err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) if err != nil { newErr.error = err.Error() - return localVarHTTPResponse, newErr + return localVarReturnValue, localVarHTTPResponse, newErr } newErr.model = v - return localVarHTTPResponse, newErr + return localVarReturnValue, localVarHTTPResponse, newErr } - if localVarHTTPResponse.StatusCode == 500 { + if localVarHTTPResponse.StatusCode == 409 { var v Error err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) if err != nil { newErr.error = err.Error() - return localVarHTTPResponse, newErr + return localVarReturnValue, localVarHTTPResponse, newErr } newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr } - return localVarHTTPResponse, newErr + if localVarHTTPResponse.StatusCode > 400 && localVarHTTPResponse.StatusCode < 500 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode >= 500 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr } - return localVarHTTPResponse, nil + err = r.apiService.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil } -type apiPinsIdGetRequest struct { +type apiPinsRequestidDeleteRequest struct { ctx _context.Context apiService *PinsApiService - id string + requestid string } /* -PinsIdGet Get pin object -Get a pin object and its status +PinsRequestidDelete Remove pin object +Remove a pin object * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - * @param id -@return apiPinsIdGetRequest + * @param requestid +@return apiPinsRequestidDeleteRequest */ -func (a *PinsApiService) PinsIdGet(ctx _context.Context, id string) apiPinsIdGetRequest { - return apiPinsIdGetRequest{ +func (a *PinsApiService) PinsRequestidDelete(ctx _context.Context, requestid string) apiPinsRequestidDeleteRequest { + return apiPinsRequestidDeleteRequest{ apiService: a, ctx: ctx, - id: id, + requestid: requestid, } } /* Execute executes the request - @return PinStatus + */ -func (r apiPinsIdGetRequest) Execute() (PinStatus, *_nethttp.Response, error) { +func (r apiPinsRequestidDeleteRequest) Execute() (*_nethttp.Response, error) { var ( - localVarHTTPMethod = _nethttp.MethodGet + localVarHTTPMethod = _nethttp.MethodDelete localVarPostBody interface{} localVarFormFileName string localVarFileName string localVarFileBytes []byte - localVarReturnValue PinStatus ) - localBasePath, err := r.apiService.client.cfg.ServerURLWithContext(r.ctx, "PinsApiService.PinsIdGet") + localBasePath, err := r.apiService.client.cfg.ServerURLWithContext(r.ctx, "PinsApiService.PinsRequestidDelete") if err != nil { - return localVarReturnValue, nil, GenericOpenAPIError{error: err.Error()} + return nil, GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/pins/{id}" - localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", _neturl.PathEscape(parameterToString(r.id, "")), -1) + localVarPath := localBasePath + "/pins/{requestid}" + localVarPath = strings.Replace(localVarPath, "{"+"requestid"+"}", _neturl.PathEscape(parameterToString(r.requestid, "")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := _neturl.Values{} @@ -399,18 +476,18 @@ func (r apiPinsIdGetRequest) Execute() (PinStatus, *_nethttp.Response, error) { } req, err := r.apiService.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes) if err != nil { - return localVarReturnValue, nil, err + return nil, err } localVarHTTPResponse, err := r.apiService.client.callAPI(req) if err != nil || localVarHTTPResponse == nil { - return localVarReturnValue, localVarHTTPResponse, err + return localVarHTTPResponse, err } localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body) localVarHTTPResponse.Body.Close() if err != nil { - return localVarReturnValue, localVarHTTPResponse, err + return localVarHTTPResponse, err } if localVarHTTPResponse.StatusCode >= 300 { @@ -423,69 +500,84 @@ func (r apiPinsIdGetRequest) Execute() (PinStatus, *_nethttp.Response, error) { err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) if err != nil { newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr + return localVarHTTPResponse, newErr } newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr + return localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.model = v + return localVarHTTPResponse, newErr } if localVarHTTPResponse.StatusCode == 404 { var v Error err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) if err != nil { newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr + return localVarHTTPResponse, newErr } newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr + return localVarHTTPResponse, newErr } - if localVarHTTPResponse.StatusCode == 500 { + if localVarHTTPResponse.StatusCode == 409 { var v Error err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) if err != nil { newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr + return localVarHTTPResponse, newErr } newErr.model = v + return localVarHTTPResponse, newErr } - return localVarReturnValue, localVarHTTPResponse, newErr - } - - err = r.apiService.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr := GenericOpenAPIError{ - body: localVarBody, - error: err.Error(), + if localVarHTTPResponse.StatusCode > 400 && localVarHTTPResponse.StatusCode < 500 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.model = v + return localVarHTTPResponse, newErr } - return localVarReturnValue, localVarHTTPResponse, newErr + if localVarHTTPResponse.StatusCode >= 500 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.model = v + } + return localVarHTTPResponse, newErr } - return localVarReturnValue, localVarHTTPResponse, nil + return localVarHTTPResponse, nil } -type apiPinsIdPostRequest struct { +type apiPinsRequestidGetRequest struct { ctx _context.Context apiService *PinsApiService - id string - pin *Pin -} - -func (r apiPinsIdPostRequest) Pin(pin Pin) apiPinsIdPostRequest { - r.pin = &pin - return r + requestid string } /* -PinsIdPost Modify pin object -Modify an existing pin object +PinsRequestidGet Get pin object +Get a pin object and its status * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - * @param id -@return apiPinsIdPostRequest + * @param requestid +@return apiPinsRequestidGetRequest */ -func (a *PinsApiService) PinsIdPost(ctx _context.Context, id string) apiPinsIdPostRequest { - return apiPinsIdPostRequest{ +func (a *PinsApiService) PinsRequestidGet(ctx _context.Context, requestid string) apiPinsRequestidGetRequest { + return apiPinsRequestidGetRequest{ apiService: a, ctx: ctx, - id: id, + requestid: requestid, } } @@ -493,9 +585,9 @@ func (a *PinsApiService) PinsIdPost(ctx _context.Context, id string) apiPinsIdPo Execute executes the request @return PinStatus */ -func (r apiPinsIdPostRequest) Execute() (PinStatus, *_nethttp.Response, error) { +func (r apiPinsRequestidGetRequest) Execute() (PinStatus, *_nethttp.Response, error) { var ( - localVarHTTPMethod = _nethttp.MethodPost + localVarHTTPMethod = _nethttp.MethodGet localVarPostBody interface{} localVarFormFileName string localVarFileName string @@ -503,24 +595,20 @@ func (r apiPinsIdPostRequest) Execute() (PinStatus, *_nethttp.Response, error) { localVarReturnValue PinStatus ) - localBasePath, err := r.apiService.client.cfg.ServerURLWithContext(r.ctx, "PinsApiService.PinsIdPost") + localBasePath, err := r.apiService.client.cfg.ServerURLWithContext(r.ctx, "PinsApiService.PinsRequestidGet") if err != nil { return localVarReturnValue, nil, GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/pins/{id}" - localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", _neturl.PathEscape(parameterToString(r.id, "")), -1) + localVarPath := localBasePath + "/pins/{requestid}" + localVarPath = strings.Replace(localVarPath, "{"+"requestid"+"}", _neturl.PathEscape(parameterToString(r.requestid, "")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := _neturl.Values{} localVarFormParams := _neturl.Values{} - if r.pin == nil { - return localVarReturnValue, nil, reportError("pin is required and must be specified") - } - // to determine the Content-Type header - localVarHTTPContentTypes := []string{"application/json"} + localVarHTTPContentTypes := []string{} // set Content-Type header localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) @@ -536,8 +624,6 @@ func (r apiPinsIdPostRequest) Execute() (PinStatus, *_nethttp.Response, error) { if localVarHTTPHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } - // body params - localVarPostBody = r.pin req, err := r.apiService.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes) if err != nil { return localVarReturnValue, nil, err @@ -599,7 +685,17 @@ func (r apiPinsIdPostRequest) Execute() (PinStatus, *_nethttp.Response, error) { newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } - if localVarHTTPResponse.StatusCode == 500 { + if localVarHTTPResponse.StatusCode > 400 && localVarHTTPResponse.StatusCode < 500 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode >= 500 { var v Error err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) if err != nil { @@ -623,27 +719,30 @@ func (r apiPinsIdPostRequest) Execute() (PinStatus, *_nethttp.Response, error) { return localVarReturnValue, localVarHTTPResponse, nil } -type apiPinsPostRequest struct { +type apiPinsRequestidPostRequest struct { ctx _context.Context apiService *PinsApiService + requestid string pin *Pin } -func (r apiPinsPostRequest) Pin(pin Pin) apiPinsPostRequest { +func (r apiPinsRequestidPostRequest) Pin(pin Pin) apiPinsRequestidPostRequest { r.pin = &pin return r } /* -PinsPost Add pin object -Add a new pin object for the current access token +PinsRequestidPost Replace pin object +Replace an existing pin object (shortcut for executing remove and add operations in one step to avoid unnecessary garbage collection of blocks present in both recursive pins) * @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). -@return apiPinsPostRequest + * @param requestid +@return apiPinsRequestidPostRequest */ -func (a *PinsApiService) PinsPost(ctx _context.Context) apiPinsPostRequest { - return apiPinsPostRequest{ +func (a *PinsApiService) PinsRequestidPost(ctx _context.Context, requestid string) apiPinsRequestidPostRequest { + return apiPinsRequestidPostRequest{ apiService: a, ctx: ctx, + requestid: requestid, } } @@ -651,7 +750,7 @@ func (a *PinsApiService) PinsPost(ctx _context.Context) apiPinsPostRequest { Execute executes the request @return PinStatus */ -func (r apiPinsPostRequest) Execute() (PinStatus, *_nethttp.Response, error) { +func (r apiPinsRequestidPostRequest) Execute() (PinStatus, *_nethttp.Response, error) { var ( localVarHTTPMethod = _nethttp.MethodPost localVarPostBody interface{} @@ -661,12 +760,13 @@ func (r apiPinsPostRequest) Execute() (PinStatus, *_nethttp.Response, error) { localVarReturnValue PinStatus ) - localBasePath, err := r.apiService.client.cfg.ServerURLWithContext(r.ctx, "PinsApiService.PinsPost") + localBasePath, err := r.apiService.client.cfg.ServerURLWithContext(r.ctx, "PinsApiService.PinsRequestidPost") if err != nil { return localVarReturnValue, nil, GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/pins" + localVarPath := localBasePath + "/pins/{requestid}" + localVarPath = strings.Replace(localVarPath, "{"+"requestid"+"}", _neturl.PathEscape(parameterToString(r.requestid, "")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := _neturl.Values{} @@ -756,7 +856,17 @@ func (r apiPinsPostRequest) Execute() (PinStatus, *_nethttp.Response, error) { newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } - if localVarHTTPResponse.StatusCode == 500 { + if localVarHTTPResponse.StatusCode > 400 && localVarHTTPResponse.StatusCode < 500 { + var v Error + err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode >= 500 { var v Error err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) if err != nil { diff --git a/pinning/remote/client/openapi/client.go b/pinning/remote/client/openapi/client.go index 2fa0b79ab..14a9d5f0c 100644 --- a/pinning/remote/client/openapi/client.go +++ b/pinning/remote/client/openapi/client.go @@ -1,7 +1,7 @@ /* * IPFS Pinning Service API * - * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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. + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 * Generated by: OpenAPI Generator (https://openapi-generator.tech) diff --git a/pinning/remote/client/openapi/configuration.go b/pinning/remote/client/openapi/configuration.go index 2dd763a9d..618454bca 100644 --- a/pinning/remote/client/openapi/configuration.go +++ b/pinning/remote/client/openapi/configuration.go @@ -1,7 +1,7 @@ /* * IPFS Pinning Service API * - * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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. + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 * Generated by: OpenAPI Generator (https://openapi-generator.tech) diff --git a/pinning/remote/client/openapi/docs/Error.md b/pinning/remote/client/openapi/docs/Error.md index e88553965..762903943 100644 --- a/pinning/remote/client/openapi/docs/Error.md +++ b/pinning/remote/client/openapi/docs/Error.md @@ -4,14 +4,13 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**Code** | **int32** | | -**Message** | **string** | | +**Error** | [**ErrorError**](Error_error.md) | | ## Methods ### NewError -`func NewError(code int32, message string, ) *Error` +`func NewError(error_ ErrorError, ) *Error` NewError instantiates a new Error object This constructor will assign default values to properties that have it defined, @@ -26,44 +25,24 @@ NewErrorWithDefaults instantiates a new Error 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 -### GetCode +### GetError -`func (o *Error) GetCode() int32` +`func (o *Error) GetError() ErrorError` -GetCode returns the Code field if non-nil, zero value otherwise. +GetError returns the Error field if non-nil, zero value otherwise. -### GetCodeOk +### GetErrorOk -`func (o *Error) GetCodeOk() (*int32, bool)` +`func (o *Error) GetErrorOk() (*ErrorError, bool)` -GetCodeOk returns a tuple with the Code field if it's non-nil, zero value otherwise +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. -### SetCode +### SetError -`func (o *Error) SetCode(v int32)` +`func (o *Error) SetError(v ErrorError)` -SetCode sets Code field to given value. - - -### GetMessage - -`func (o *Error) GetMessage() string` - -GetMessage returns the Message field if non-nil, zero value otherwise. - -### GetMessageOk - -`func (o *Error) GetMessageOk() (*string, bool)` - -GetMessageOk returns a tuple with the Message field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetMessage - -`func (o *Error) SetMessage(v string)` - -SetMessage sets Message field to given value. +SetError sets Error field to given value. diff --git a/pinning/remote/client/openapi/docs/ErrorError.md b/pinning/remote/client/openapi/docs/ErrorError.md new file mode 100644 index 000000000..e44d63829 --- /dev/null +++ b/pinning/remote/client/openapi/docs/ErrorError.md @@ -0,0 +1,77 @@ +# ErrorError + +## 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 + +### NewErrorError + +`func NewErrorError(reason string, ) *ErrorError` + +NewErrorError instantiates a new ErrorError 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 + +### NewErrorErrorWithDefaults + +`func NewErrorErrorWithDefaults() *ErrorError` + +NewErrorErrorWithDefaults instantiates a new ErrorError 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 *ErrorError) GetReason() string` + +GetReason returns the Reason field if non-nil, zero value otherwise. + +### GetReasonOk + +`func (o *ErrorError) 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 *ErrorError) SetReason(v string)` + +SetReason sets Reason field to given value. + + +### GetDetails + +`func (o *ErrorError) GetDetails() string` + +GetDetails returns the Details field if non-nil, zero value otherwise. + +### GetDetailsOk + +`func (o *ErrorError) 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 *ErrorError) SetDetails(v string)` + +SetDetails sets Details field to given value. + +### HasDetails + +`func (o *ErrorError) 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) + + diff --git a/pinning/remote/client/openapi/docs/Pin.md b/pinning/remote/client/openapi/docs/Pin.md index cbdf1a0b7..e5d3e0f18 100644 --- a/pinning/remote/client/openapi/docs/Pin.md +++ b/pinning/remote/client/openapi/docs/Pin.md @@ -4,7 +4,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**Cid** | **string** | CID to be pinned recursively | +**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] diff --git a/pinning/remote/client/openapi/docs/PinStatus.md b/pinning/remote/client/openapi/docs/PinStatus.md index 2408abfda..40ae992ab 100644 --- a/pinning/remote/client/openapi/docs/PinStatus.md +++ b/pinning/remote/client/openapi/docs/PinStatus.md @@ -4,7 +4,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**Id** | **string** | Globally unique ID of the pin request; can be used to check the status of ongoing pinning, modification of pin object, or pin removal | +**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) | | @@ -15,7 +15,7 @@ Name | Type | Description | Notes ### NewPinStatus -`func NewPinStatus(id string, status Status, created time.Time, pin Pin, delegates []string, ) *PinStatus` +`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, @@ -30,24 +30,24 @@ 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 -### GetId +### GetRequestid -`func (o *PinStatus) GetId() string` +`func (o *PinStatus) GetRequestid() string` -GetId returns the Id field if non-nil, zero value otherwise. +GetRequestid returns the Requestid field if non-nil, zero value otherwise. -### GetIdOk +### GetRequestidOk -`func (o *PinStatus) GetIdOk() (*string, bool)` +`func (o *PinStatus) GetRequestidOk() (*string, bool)` -GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +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. -### SetId +### SetRequestid -`func (o *PinStatus) SetId(v string)` +`func (o *PinStatus) SetRequestid(v string)` -SetId sets Id field to given value. +SetRequestid sets Requestid field to given value. ### GetStatus diff --git a/pinning/remote/client/openapi/docs/PinsApi.md b/pinning/remote/client/openapi/docs/PinsApi.md index 0aea62d99..00cff667b 100644 --- a/pinning/remote/client/openapi/docs/PinsApi.md +++ b/pinning/remote/client/openapi/docs/PinsApi.md @@ -5,10 +5,10 @@ All URIs are relative to *https://pinning-service.example.com* Method | HTTP request | Description ------------- | ------------- | ------------- [**PinsGet**](PinsApi.md#PinsGet) | **Get** /pins | List pin objects -[**PinsIdDelete**](PinsApi.md#PinsIdDelete) | **Delete** /pins/{id} | Remove pin object -[**PinsIdGet**](PinsApi.md#PinsIdGet) | **Get** /pins/{id} | Get pin object -[**PinsIdPost**](PinsApi.md#PinsIdPost) | **Post** /pins/{id} | Modify pin object [**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 @@ -33,8 +33,8 @@ import ( ) func main() { - cid := []string{"Inner_example"} // []string | Return pin objects responsible for pinning the specified CID(s) (optional) - name := "name_example" // string | Return pin objects with names that contain provided value (partial or full match) (optional) + 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) @@ -64,8 +64,8 @@ Other parameters are passed through a pointer to a apiPinsGetRequest struct via Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **cid** | [**[]string**](string.md) | Return pin objects responsible for pinning the specified CID(s) | - **name** | **string** | Return pin objects with names that contain provided value (partial or full match) | + **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 | @@ -90,11 +90,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## PinsIdDelete +## PinsPost -> PinsIdDelete(ctx, id).Execute() +> PinStatus PinsPost(ctx).Pin(pin).Execute() -Remove pin object +Add pin object @@ -111,38 +111,36 @@ import ( ) func main() { - id := "id_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.PinsIdDelete(context.Background(), id).Execute() + resp, r, err := api_client.PinsApi.PinsPost(context.Background(), pin).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `PinsApi.PinsIdDelete``: %v\n", err) + 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 -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- -**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**id** | **string** | | ### Other Parameters -Other parameters are passed through a pointer to a apiPinsIdDeleteRequest struct via the builder pattern +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 - (empty response body) +[**PinStatus**](PinStatus.md) ### Authorization @@ -150,7 +148,7 @@ Name | Type | Description | Notes ### HTTP request headers -- **Content-Type**: Not defined +- **Content-Type**: application/json - **Accept**: application/json [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) @@ -158,11 +156,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## PinsIdGet +## PinsRequestidDelete -> PinStatus PinsIdGet(ctx, id).Execute() +> PinsRequestidDelete(ctx, requestid).Execute() -Get pin object +Remove pin object @@ -179,17 +177,15 @@ import ( ) func main() { - id := "id_example" // string | + requestid := "requestid_example" // string | configuration := openapiclient.NewConfiguration() api_client := openapiclient.NewAPIClient(configuration) - resp, r, err := api_client.PinsApi.PinsIdGet(context.Background(), id).Execute() + resp, r, err := api_client.PinsApi.PinsRequestidDelete(context.Background(), requestid).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `PinsApi.PinsIdGet``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `PinsApi.PinsRequestidDelete``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `PinsIdGet`: PinStatus - fmt.Fprintf(os.Stdout, "Response from `PinsApi.PinsIdGet`: %v\n", resp) } ``` @@ -199,11 +195,11 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**id** | **string** | | +**requestid** | **string** | | ### Other Parameters -Other parameters are passed through a pointer to a apiPinsIdGetRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiPinsRequestidDeleteRequest struct via the builder pattern Name | Type | Description | Notes @@ -212,7 +208,7 @@ Name | Type | Description | Notes ### Return type -[**PinStatus**](PinStatus.md) + (empty response body) ### Authorization @@ -228,11 +224,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## PinsIdPost +## PinsRequestidGet -> PinStatus PinsIdPost(ctx, id).Pin(pin).Execute() +> PinStatus PinsRequestidGet(ctx, requestid).Execute() -Modify pin object +Get pin object @@ -249,18 +245,17 @@ import ( ) func main() { - id := "id_example" // string | - pin := openapiclient.Pin{Cid: "Cid_example", Name: "Name_example", Origins: []string{"Origins_example"), Meta: map[string]string{ "Key" = "Value" }} // Pin | + requestid := "requestid_example" // string | configuration := openapiclient.NewConfiguration() api_client := openapiclient.NewAPIClient(configuration) - resp, r, err := api_client.PinsApi.PinsIdPost(context.Background(), id, pin).Execute() + resp, r, err := api_client.PinsApi.PinsRequestidGet(context.Background(), requestid).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `PinsApi.PinsIdPost``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `PinsApi.PinsRequestidGet``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `PinsIdPost`: PinStatus - fmt.Fprintf(os.Stdout, "Response from `PinsApi.PinsIdPost`: %v\n", resp) + // response from `PinsRequestidGet`: PinStatus + fmt.Fprintf(os.Stdout, "Response from `PinsApi.PinsRequestidGet`: %v\n", resp) } ``` @@ -270,17 +265,16 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**id** | **string** | | +**requestid** | **string** | | ### Other Parameters -Other parameters are passed through a pointer to a apiPinsIdPostRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiPinsRequestidGetRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **pin** | [**Pin**](Pin.md) | | ### Return type @@ -292,7 +286,7 @@ Name | Type | Description | Notes ### HTTP request headers -- **Content-Type**: application/json +- **Content-Type**: Not defined - **Accept**: application/json [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) @@ -300,11 +294,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## PinsPost +## PinsRequestidPost -> PinStatus PinsPost(ctx).Pin(pin).Execute() +> PinStatus PinsRequestidPost(ctx, requestid).Pin(pin).Execute() -Add pin object +Replace pin object @@ -321,31 +315,37 @@ import ( ) 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.PinsPost(context.Background(), pin).Execute() + resp, r, err := api_client.PinsApi.PinsRequestidPost(context.Background(), requestid, pin).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `PinsApi.PinsPost``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `PinsApi.PinsRequestidPost``: %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) + // 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 apiPinsPostRequest struct via the builder pattern +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 diff --git a/pinning/remote/client/openapi/model_error.go b/pinning/remote/client/openapi/model_error.go index d97ecaa2c..ab308de3d 100644 --- a/pinning/remote/client/openapi/model_error.go +++ b/pinning/remote/client/openapi/model_error.go @@ -1,7 +1,7 @@ /* * IPFS Pinning Service API * - * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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. + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 * Generated by: OpenAPI Generator (https://openapi-generator.tech) @@ -13,20 +13,18 @@ import ( "encoding/json" ) -// Error Base error object +// Error Error object type Error struct { - Code int32 `json:"code"` - Message string `json:"message"` + Error ErrorError `json:"error"` } // NewError instantiates a new Error 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 NewError(code int32, message string) *Error { +func NewError(error_ ErrorError) *Error { this := Error{} - this.Code = code - this.Message = message + this.Error = error_ return &this } @@ -38,61 +36,34 @@ func NewErrorWithDefaults() *Error { return &this } -// GetCode returns the Code field value -func (o *Error) GetCode() int32 { +// GetError returns the Error field value +func (o *Error) GetError() ErrorError { if o == nil { - var ret int32 + var ret ErrorError return ret } - return o.Code + return o.Error } -// GetCodeOk returns a tuple with the Code field value +// GetErrorOk returns a tuple with the Error field value // and a boolean to check if the value has been set. -func (o *Error) GetCodeOk() (*int32, bool) { +func (o *Error) GetErrorOk() (*ErrorError, bool) { if o == nil { return nil, false } - return &o.Code, true + return &o.Error, true } -// SetCode sets field value -func (o *Error) SetCode(v int32) { - o.Code = v -} - -// GetMessage returns the Message field value -func (o *Error) GetMessage() string { - if o == nil { - var ret string - return ret - } - - return o.Message -} - -// GetMessageOk returns a tuple with the Message field value -// and a boolean to check if the value has been set. -func (o *Error) GetMessageOk() (*string, bool) { - if o == nil { - return nil, false - } - return &o.Message, true -} - -// SetMessage sets field value -func (o *Error) SetMessage(v string) { - o.Message = v +// SetError sets field value +func (o *Error) SetError(v ErrorError) { + o.Error = v } func (o Error) MarshalJSON() ([]byte, error) { toSerialize := map[string]interface{}{} if true { - toSerialize["code"] = o.Code - } - if true { - toSerialize["message"] = o.Message + toSerialize["error"] = o.Error } return json.Marshal(toSerialize) } diff --git a/pinning/remote/client/openapi/model_error_error.go b/pinning/remote/client/openapi/model_error_error.go new file mode 100644 index 000000000..0a177dbd2 --- /dev/null +++ b/pinning/remote/client/openapi/model_error_error.go @@ -0,0 +1,143 @@ +/* + * IPFS Pinning Service API + * + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "encoding/json" +) + +// ErrorError struct for ErrorError +type ErrorError 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"` +} + +// NewErrorError instantiates a new ErrorError 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 NewErrorError(reason string) *ErrorError { + this := ErrorError{} + this.Reason = reason + return &this +} + +// NewErrorErrorWithDefaults instantiates a new ErrorError 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 NewErrorErrorWithDefaults() *ErrorError { + this := ErrorError{} + return &this +} + +// GetReason returns the Reason field value +func (o *ErrorError) 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 *ErrorError) GetReasonOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Reason, true +} + +// SetReason sets field value +func (o *ErrorError) SetReason(v string) { + o.Reason = v +} + +// GetDetails returns the Details field value if set, zero value otherwise. +func (o *ErrorError) 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 *ErrorError) 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 *ErrorError) 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 *ErrorError) SetDetails(v string) { + o.Details = &v +} + +func (o ErrorError) 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 NullableErrorError struct { + value *ErrorError + isSet bool +} + +func (v NullableErrorError) Get() *ErrorError { + return v.value +} + +func (v *NullableErrorError) Set(val *ErrorError) { + v.value = val + v.isSet = true +} + +func (v NullableErrorError) IsSet() bool { + return v.isSet +} + +func (v *NullableErrorError) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableErrorError(val *ErrorError) *NullableErrorError { + return &NullableErrorError{value: val, isSet: true} +} + +func (v NullableErrorError) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableErrorError) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pinning/remote/client/openapi/model_pin.go b/pinning/remote/client/openapi/model_pin.go index c4a5e8015..31ae0ca86 100644 --- a/pinning/remote/client/openapi/model_pin.go +++ b/pinning/remote/client/openapi/model_pin.go @@ -1,7 +1,7 @@ /* * IPFS Pinning Service API * - * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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. + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 * Generated by: OpenAPI Generator (https://openapi-generator.tech) @@ -15,7 +15,7 @@ import ( // Pin Pin object type Pin struct { - // CID to be pinned recursively + // 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"` diff --git a/pinning/remote/client/openapi/model_pin_results.go b/pinning/remote/client/openapi/model_pin_results.go index ac8443976..b569fe5df 100644 --- a/pinning/remote/client/openapi/model_pin_results.go +++ b/pinning/remote/client/openapi/model_pin_results.go @@ -1,7 +1,7 @@ /* * IPFS Pinning Service API * - * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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. + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 * Generated by: OpenAPI Generator (https://openapi-generator.tech) diff --git a/pinning/remote/client/openapi/model_pin_status.go b/pinning/remote/client/openapi/model_pin_status.go index 78f37dcd2..21d7992b2 100644 --- a/pinning/remote/client/openapi/model_pin_status.go +++ b/pinning/remote/client/openapi/model_pin_status.go @@ -1,7 +1,7 @@ /* * IPFS Pinning Service API * - * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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. + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 * Generated by: OpenAPI Generator (https://openapi-generator.tech) @@ -16,9 +16,9 @@ import ( // PinStatus Pin object with status type PinStatus struct { - // Globally unique ID of the pin request; can be used to check the status of ongoing pinning, modification of pin object, or pin removal - Id string `json:"id"` - Status Status `json:"status"` + // Globally unique identifier of the pin request; can be used to check the status of ongoing pinning, or pin removal + Requestid string `json:"requestid"` + Status Status `json:"status"` // Immutable timestamp indicating when a pin request entered a pinning service; can be used for filtering results and pagination Created time.Time `json:"created"` Pin Pin `json:"pin"` @@ -32,9 +32,9 @@ type PinStatus struct { // 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 NewPinStatus(id string, status Status, created time.Time, pin Pin, delegates []string) *PinStatus { +func NewPinStatus(requestid string, status Status, created time.Time, pin Pin, delegates []string) *PinStatus { this := PinStatus{} - this.Id = id + this.Requestid = requestid this.Status = status this.Created = created this.Pin = pin @@ -50,28 +50,28 @@ func NewPinStatusWithDefaults() *PinStatus { return &this } -// GetId returns the Id field value -func (o *PinStatus) GetId() string { +// GetRequestid returns the Requestid field value +func (o *PinStatus) GetRequestid() string { if o == nil { var ret string return ret } - return o.Id + return o.Requestid } -// GetIdOk returns a tuple with the Id field value +// GetRequestidOk returns a tuple with the Requestid field value // and a boolean to check if the value has been set. -func (o *PinStatus) GetIdOk() (*string, bool) { +func (o *PinStatus) GetRequestidOk() (*string, bool) { if o == nil { return nil, false } - return &o.Id, true + return &o.Requestid, true } -// SetId sets field value -func (o *PinStatus) SetId(v string) { - o.Id = v +// SetRequestid sets field value +func (o *PinStatus) SetRequestid(v string) { + o.Requestid = v } // GetStatus returns the Status field value @@ -205,7 +205,7 @@ func (o *PinStatus) SetInfo(v map[string]string) { func (o PinStatus) MarshalJSON() ([]byte, error) { toSerialize := map[string]interface{}{} if true { - toSerialize["id"] = o.Id + toSerialize["requestid"] = o.Requestid } if true { toSerialize["status"] = o.Status diff --git a/pinning/remote/client/openapi/model_status.go b/pinning/remote/client/openapi/model_status.go index fe727407e..7b30371ba 100644 --- a/pinning/remote/client/openapi/model_status.go +++ b/pinning/remote/client/openapi/model_status.go @@ -1,7 +1,7 @@ /* * IPFS Pinning Service API * - * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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. + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 * Generated by: OpenAPI Generator (https://openapi-generator.tech) diff --git a/pinning/remote/client/openapi/response.go b/pinning/remote/client/openapi/response.go index d053bb91f..5f1b37456 100644 --- a/pinning/remote/client/openapi/response.go +++ b/pinning/remote/client/openapi/response.go @@ -1,7 +1,7 @@ /* * IPFS Pinning Service API * - * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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. + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 * Generated by: OpenAPI Generator (https://openapi-generator.tech) diff --git a/pinning/remote/client/openapi/utils.go b/pinning/remote/client/openapi/utils.go index a5daa9247..976239127 100644 --- a/pinning/remote/client/openapi/utils.go +++ b/pinning/remote/client/openapi/utils.go @@ -1,7 +1,7 @@ /* * IPFS Pinning Service API * - * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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). ## Objects ### Pin object ![pinning-services-api-pin-object.png](https://bafybeidcoyxd723nakggdayy6qg25bl7mls3ilwwiyxmys5qpek7y6jwc4.ipfs.dweb.link/?filename=pinning-services-api-pin-object.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 ![pinning-services-api-pin-status-response.png](https://bafybeiec3c3gzsus4rksddsuxcybilex3odq5cm2cyrzrb7m3suwspl6uy.ipfs.dweb.link/?filename=pinning-services-api-pin-status-response.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 `id` 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-services-api-objects.png](https://bafybeigyefq6vwfcsi7dfgqunf4uei426lvia3w73ylg4kgdwwg6txivpe.ipfs.dweb.link/?filename=pinning-services-api-objects.png) ### Creating a new pin object The user sends a `Pin` object to `POST /pins` and receives a `PinStatus` response: - `id` in `PinStatus` is the identifier of the pin operation, which can can be used for checking status, modifying the pin, and/or 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/{id}` until pinning is successful, or the user decides to remove the pending pin. ### Modifying an existing pin object The user can modify an existing pin object via `POST /pins/{id}`. The new pin object `id` 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/{id}`. ## 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\":}` - `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. + * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 * Generated by: OpenAPI Generator (https://openapi-generator.tech) From 941227de7a1b2be5605d1c54d6686c780cda686e Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 15 Oct 2020 15:23:19 -0400 Subject: [PATCH 6/8] docs: Update README with codegen instructions This commit was moved from ipfs/go-pinning-service-http-client@df65dc336ff0a790d84cb61487edad99886913c8 --- pinning/remote/client/README.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/pinning/remote/client/README.md b/pinning/remote/client/README.md index 213f0df83..0326b556c 100644 --- a/pinning/remote/client/README.md +++ b/pinning/remote/client/README.md @@ -13,10 +13,27 @@ An IPFS Pinning Service HTTP Client [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) \ No newline at end of file +[SPDX-License-Identifier: Apache-2.0 OR MIT](LICENSE.md) From 4e02944ed6940d10f7b9e50e8c328e359ef8f191 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 15 Oct 2020 15:28:18 -0400 Subject: [PATCH 7/8] cleaned up client error processing This commit was moved from ipfs/go-pinning-service-http-client@b37b2d435ea52173793aeaf94f40f49e63322d44 --- pinning/remote/client/client.go | 43 ++++++--------------------------- 1 file changed, 8 insertions(+), 35 deletions(-) diff --git a/pinning/remote/client/client.go b/pinning/remote/client/client.go index f021abb08..e3c04176e 100644 --- a/pinning/remote/client/client.go +++ b/pinning/remote/client/client.go @@ -1,10 +1,9 @@ package go_pinning_service_http_client import ( - "bytes" "context" - "encoding/json" "fmt" + "github.com/pkg/errors" "net/http" "time" @@ -38,11 +37,6 @@ func NewClient(url, bearerToken string) *Client { return &Client{client: openapi.NewAPIClient(config)} } -func getError(e *openapi.Error) error { - err := e.GetError() - return fmt.Errorf("request error: %s - %s", err.GetReason(), err.GetDetails()) -} - // TODO: We should probably make sure there are no duplicates sent type lsSettings struct { cids []string @@ -374,37 +368,16 @@ func getCIDEncoder() multibase.Encoder { func httperr(resp *http.Response, e error) error { oerr, ok := e.(openapi.GenericOpenAPIError) - if !ok { - panic("wrong error type") - } - var buf bytes.Buffer - var err error - - var reqStr string - if resp.Request.GetBody != nil { - resp.Request.Body, err = resp.Request.GetBody() - if err != nil { - reqStr = err.Error() - } else if err := resp.Request.Write(&buf); err != nil { - reqStr = err.Error() - } else { - reqStr = buf.String() + if ok { + ferr, ok := oerr.Model().(openapi.Failure) + if ok { + return errors.Wrapf(e,"statusCode: %d, reason : %q, details : %q", resp.StatusCode, ferr.Error.GetReason(), ferr.Error.GetDetails()) } - } else { - reqStr = resp.Request.URL.String() } - bodystr := string(oerr.Body()) - //body, err := ioutil.ReadAll(resp.Body) - //var bodystr string - //if err == nil { - // bodystr = string(body) - //} - relevantErr := fmt.Sprintf("{ httpcode: %d, httpresp: %s, httpbody: %s, reqstr: %s }", resp.StatusCode, resp.Status, bodystr, reqStr) - relevantErrBytes, err := json.MarshalIndent(relevantErr, "", "\t") - if err != nil { - return fmt.Errorf("RelevantInfo : %s, MarshalErr: %s, Err: %w", relevantErr, err, e) + if resp == nil { + return errors.Wrapf(e,"empty response from remote pinning service") } - return fmt.Errorf("relevantErr: %s, err: %w", relevantErrBytes, e) + return errors.Wrapf(e, "remote pinning service error. statusCode: %d", resp.StatusCode) } From 380ca9d435e00494b4e54580ab0c98af3f6258f0 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 15 Oct 2020 15:27:44 -0400 Subject: [PATCH 8/8] feat: bumped spec to v0.1.1 This commit was moved from ipfs/go-pinning-service-http-client@3159542e49a2f3caaf401a5556640cc2e625d877 --- pinning/remote/client/openapi/README.md | 6 +- pinning/remote/client/openapi/api_pins.go | 267 +----------------- pinning/remote/client/openapi/client.go | 4 +- .../remote/client/openapi/configuration.go | 2 +- .../openapi/docs/{Error.md => Failure.md} | 22 +- .../docs/{ErrorError.md => FailureError.md} | 28 +- .../{model_error.go => model_failure.go} | 50 ++-- ..._error_error.go => model_failure_error.go} | 54 ++-- pinning/remote/client/openapi/model_pin.go | 2 +- .../client/openapi/model_pin_results.go | 2 +- .../remote/client/openapi/model_pin_status.go | 2 +- pinning/remote/client/openapi/model_status.go | 2 +- pinning/remote/client/openapi/response.go | 2 +- pinning/remote/client/openapi/utils.go | 2 +- 14 files changed, 100 insertions(+), 345 deletions(-) rename pinning/remote/client/openapi/docs/{Error.md => Failure.md} (68%) rename pinning/remote/client/openapi/docs/{ErrorError.md => FailureError.md} (71%) rename pinning/remote/client/openapi/{model_error.go => model_failure.go} (89%) rename pinning/remote/client/openapi/{model_error_error.go => model_failure_error.go} (88%) diff --git a/pinning/remote/client/openapi/README.md b/pinning/remote/client/openapi/README.md index 277bbc39a..fe21b9a00 100644 --- a/pinning/remote/client/openapi/README.md +++ b/pinning/remote/client/openapi/README.md @@ -104,7 +104,7 @@ Pin objects can be listed by executing `GET /pins` with optional parameters: ## 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.0.5 +- API version: 0.1.1 - Package version: 1.0.0 - Build package: org.openapitools.codegen.languages.GoClientExperimentalCodegen @@ -180,8 +180,8 @@ Class | Method | HTTP request | Description ## Documentation For Models - - [Error](docs/Error.md) - - [ErrorError](docs/ErrorError.md) + - [Failure](docs/Failure.md) + - [FailureError](docs/FailureError.md) - [Pin](docs/Pin.md) - [PinResults](docs/PinResults.md) - [PinStatus](docs/PinStatus.md) diff --git a/pinning/remote/client/openapi/api_pins.go b/pinning/remote/client/openapi/api_pins.go index ff03d0c99..8c45df5a3 100644 --- a/pinning/remote/client/openapi/api_pins.go +++ b/pinning/remote/client/openapi/api_pins.go @@ -3,7 +3,7 @@ * * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 + * API version: 0.1.1 * Generated by: OpenAPI Generator (https://openapi-generator.tech) */ @@ -170,8 +170,8 @@ func (r apiPinsGetRequest) Execute() (PinResults, *_nethttp.Response, error) { body: localVarBody, error: localVarHTTPResponse.Status, } - if localVarHTTPResponse.StatusCode == 400 { - var v Error + if localVarHTTPResponse.StatusCode >= 400 && localVarHTTPResponse.StatusCode <= 600 { + var v Failure err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) if err != nil { newErr.error = err.Error() @@ -180,55 +180,6 @@ func (r apiPinsGetRequest) Execute() (PinResults, *_nethttp.Response, error) { newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } - if localVarHTTPResponse.StatusCode == 401 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode == 404 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode == 409 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode > 400 && localVarHTTPResponse.StatusCode < 500 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode >= 500 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - } return localVarReturnValue, localVarHTTPResponse, newErr } @@ -337,28 +288,8 @@ func (r apiPinsPostRequest) Execute() (PinStatus, *_nethttp.Response, error) { body: localVarBody, error: localVarHTTPResponse.Status, } - if localVarHTTPResponse.StatusCode == 400 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode == 401 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode == 404 { - var v Error + if localVarHTTPResponse.StatusCode >= 400 && localVarHTTPResponse.StatusCode <= 600 { + var v Failure err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) if err != nil { newErr.error = err.Error() @@ -367,35 +298,6 @@ func (r apiPinsPostRequest) Execute() (PinStatus, *_nethttp.Response, error) { newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } - if localVarHTTPResponse.StatusCode == 409 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode > 400 && localVarHTTPResponse.StatusCode < 500 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode >= 500 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - } return localVarReturnValue, localVarHTTPResponse, newErr } @@ -495,18 +397,8 @@ func (r apiPinsRequestidDeleteRequest) Execute() (*_nethttp.Response, error) { body: localVarBody, error: localVarHTTPResponse.Status, } - if localVarHTTPResponse.StatusCode == 400 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarHTTPResponse, newErr - } - newErr.model = v - return localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode == 401 { - var v Error + if localVarHTTPResponse.StatusCode >= 400 && localVarHTTPResponse.StatusCode <= 600 { + var v Failure err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) if err != nil { newErr.error = err.Error() @@ -515,45 +407,6 @@ func (r apiPinsRequestidDeleteRequest) Execute() (*_nethttp.Response, error) { newErr.model = v return localVarHTTPResponse, newErr } - if localVarHTTPResponse.StatusCode == 404 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarHTTPResponse, newErr - } - newErr.model = v - return localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode == 409 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarHTTPResponse, newErr - } - newErr.model = v - return localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode > 400 && localVarHTTPResponse.StatusCode < 500 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarHTTPResponse, newErr - } - newErr.model = v - return localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode >= 500 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarHTTPResponse, newErr - } - newErr.model = v - } return localVarHTTPResponse, newErr } @@ -645,8 +498,8 @@ func (r apiPinsRequestidGetRequest) Execute() (PinStatus, *_nethttp.Response, er body: localVarBody, error: localVarHTTPResponse.Status, } - if localVarHTTPResponse.StatusCode == 400 { - var v Error + if localVarHTTPResponse.StatusCode >= 400 && localVarHTTPResponse.StatusCode <= 600 { + var v Failure err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) if err != nil { newErr.error = err.Error() @@ -655,55 +508,6 @@ func (r apiPinsRequestidGetRequest) Execute() (PinStatus, *_nethttp.Response, er newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } - if localVarHTTPResponse.StatusCode == 401 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode == 404 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode == 409 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode > 400 && localVarHTTPResponse.StatusCode < 500 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode >= 500 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - } return localVarReturnValue, localVarHTTPResponse, newErr } @@ -816,48 +620,8 @@ func (r apiPinsRequestidPostRequest) Execute() (PinStatus, *_nethttp.Response, e body: localVarBody, error: localVarHTTPResponse.Status, } - if localVarHTTPResponse.StatusCode == 400 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode == 401 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode == 404 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode == 409 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHTTPResponse, newErr - } - if localVarHTTPResponse.StatusCode > 400 && localVarHTTPResponse.StatusCode < 500 { - var v Error + if localVarHTTPResponse.StatusCode >= 400 && localVarHTTPResponse.StatusCode <= 600 { + var v Failure err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) if err != nil { newErr.error = err.Error() @@ -866,15 +630,6 @@ func (r apiPinsRequestidPostRequest) Execute() (PinStatus, *_nethttp.Response, e newErr.model = v return localVarReturnValue, localVarHTTPResponse, newErr } - if localVarHTTPResponse.StatusCode >= 500 { - var v Error - err = r.apiService.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHTTPResponse, newErr - } - newErr.model = v - } return localVarReturnValue, localVarHTTPResponse, newErr } diff --git a/pinning/remote/client/openapi/client.go b/pinning/remote/client/openapi/client.go index 14a9d5f0c..985408987 100644 --- a/pinning/remote/client/openapi/client.go +++ b/pinning/remote/client/openapi/client.go @@ -3,7 +3,7 @@ * * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 + * API version: 0.1.1 * Generated by: OpenAPI Generator (https://openapi-generator.tech) */ @@ -39,7 +39,7 @@ var ( xmlCheck = regexp.MustCompile(`(?i:(?:application|text)/xml)`) ) -// APIClient manages communication with the IPFS Pinning Service API API v0.0.5 +// APIClient manages communication with the IPFS Pinning Service API API v0.1.1 // In most cases there should be only one, shared, APIClient. type APIClient struct { cfg *Configuration diff --git a/pinning/remote/client/openapi/configuration.go b/pinning/remote/client/openapi/configuration.go index 618454bca..2f31e1352 100644 --- a/pinning/remote/client/openapi/configuration.go +++ b/pinning/remote/client/openapi/configuration.go @@ -3,7 +3,7 @@ * * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 + * API version: 0.1.1 * Generated by: OpenAPI Generator (https://openapi-generator.tech) */ diff --git a/pinning/remote/client/openapi/docs/Error.md b/pinning/remote/client/openapi/docs/Failure.md similarity index 68% rename from pinning/remote/client/openapi/docs/Error.md rename to pinning/remote/client/openapi/docs/Failure.md index 762903943..c899f7138 100644 --- a/pinning/remote/client/openapi/docs/Error.md +++ b/pinning/remote/client/openapi/docs/Failure.md @@ -1,46 +1,46 @@ -# Error +# Failure ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**Error** | [**ErrorError**](Error_error.md) | | +**Error** | [**FailureError**](Failure_error.md) | | ## Methods -### NewError +### NewFailure -`func NewError(error_ ErrorError, ) *Error` +`func NewFailure(error_ FailureError, ) *Failure` -NewError instantiates a new Error object +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 -### NewErrorWithDefaults +### NewFailureWithDefaults -`func NewErrorWithDefaults() *Error` +`func NewFailureWithDefaults() *Failure` -NewErrorWithDefaults instantiates a new Error object +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 *Error) GetError() ErrorError` +`func (o *Failure) GetError() FailureError` GetError returns the Error field if non-nil, zero value otherwise. ### GetErrorOk -`func (o *Error) GetErrorOk() (*ErrorError, bool)` +`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 *Error) SetError(v ErrorError)` +`func (o *Failure) SetError(v FailureError)` SetError sets Error field to given value. diff --git a/pinning/remote/client/openapi/docs/ErrorError.md b/pinning/remote/client/openapi/docs/FailureError.md similarity index 71% rename from pinning/remote/client/openapi/docs/ErrorError.md rename to pinning/remote/client/openapi/docs/FailureError.md index e44d63829..478f1b942 100644 --- a/pinning/remote/client/openapi/docs/ErrorError.md +++ b/pinning/remote/client/openapi/docs/FailureError.md @@ -1,4 +1,4 @@ -# ErrorError +# FailureError ## Properties @@ -9,65 +9,65 @@ Name | Type | Description | Notes ## Methods -### NewErrorError +### NewFailureError -`func NewErrorError(reason string, ) *ErrorError` +`func NewFailureError(reason string, ) *FailureError` -NewErrorError instantiates a new ErrorError object +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 -### NewErrorErrorWithDefaults +### NewFailureErrorWithDefaults -`func NewErrorErrorWithDefaults() *ErrorError` +`func NewFailureErrorWithDefaults() *FailureError` -NewErrorErrorWithDefaults instantiates a new ErrorError object +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 *ErrorError) GetReason() string` +`func (o *FailureError) GetReason() string` GetReason returns the Reason field if non-nil, zero value otherwise. ### GetReasonOk -`func (o *ErrorError) GetReasonOk() (*string, bool)` +`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 *ErrorError) SetReason(v string)` +`func (o *FailureError) SetReason(v string)` SetReason sets Reason field to given value. ### GetDetails -`func (o *ErrorError) GetDetails() string` +`func (o *FailureError) GetDetails() string` GetDetails returns the Details field if non-nil, zero value otherwise. ### GetDetailsOk -`func (o *ErrorError) GetDetailsOk() (*string, bool)` +`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 *ErrorError) SetDetails(v string)` +`func (o *FailureError) SetDetails(v string)` SetDetails sets Details field to given value. ### HasDetails -`func (o *ErrorError) HasDetails() bool` +`func (o *FailureError) HasDetails() bool` HasDetails returns a boolean if a field has been set. diff --git a/pinning/remote/client/openapi/model_error.go b/pinning/remote/client/openapi/model_failure.go similarity index 89% rename from pinning/remote/client/openapi/model_error.go rename to pinning/remote/client/openapi/model_failure.go index ab308de3d..ec1fc8268 100644 --- a/pinning/remote/client/openapi/model_error.go +++ b/pinning/remote/client/openapi/model_failure.go @@ -3,7 +3,7 @@ * * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 + * API version: 0.1.1 * Generated by: OpenAPI Generator (https://openapi-generator.tech) */ @@ -13,33 +13,33 @@ import ( "encoding/json" ) -// Error Error object -type Error struct { - Error ErrorError `json:"error"` +// Failure Response for a failed request +type Failure struct { + Error FailureError `json:"error"` } -// NewError instantiates a new Error object +// 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 NewError(error_ ErrorError) *Error { - this := Error{} +func NewFailure(error_ FailureError) *Failure { + this := Failure{} this.Error = error_ return &this } -// NewErrorWithDefaults instantiates a new Error object +// 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 NewErrorWithDefaults() *Error { - this := Error{} +func NewFailureWithDefaults() *Failure { + this := Failure{} return &this } // GetError returns the Error field value -func (o *Error) GetError() ErrorError { +func (o *Failure) GetError() FailureError { if o == nil { - var ret ErrorError + var ret FailureError return ret } @@ -48,7 +48,7 @@ func (o *Error) GetError() ErrorError { // GetErrorOk returns a tuple with the Error field value // and a boolean to check if the value has been set. -func (o *Error) GetErrorOk() (*ErrorError, bool) { +func (o *Failure) GetErrorOk() (*FailureError, bool) { if o == nil { return nil, false } @@ -56,11 +56,11 @@ func (o *Error) GetErrorOk() (*ErrorError, bool) { } // SetError sets field value -func (o *Error) SetError(v ErrorError) { +func (o *Failure) SetError(v FailureError) { o.Error = v } -func (o Error) MarshalJSON() ([]byte, error) { +func (o Failure) MarshalJSON() ([]byte, error) { toSerialize := map[string]interface{}{} if true { toSerialize["error"] = o.Error @@ -68,38 +68,38 @@ func (o Error) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -type NullableError struct { - value *Error +type NullableFailure struct { + value *Failure isSet bool } -func (v NullableError) Get() *Error { +func (v NullableFailure) Get() *Failure { return v.value } -func (v *NullableError) Set(val *Error) { +func (v *NullableFailure) Set(val *Failure) { v.value = val v.isSet = true } -func (v NullableError) IsSet() bool { +func (v NullableFailure) IsSet() bool { return v.isSet } -func (v *NullableError) Unset() { +func (v *NullableFailure) Unset() { v.value = nil v.isSet = false } -func NewNullableError(val *Error) *NullableError { - return &NullableError{value: val, isSet: true} +func NewNullableFailure(val *Failure) *NullableFailure { + return &NullableFailure{value: val, isSet: true} } -func (v NullableError) MarshalJSON() ([]byte, error) { +func (v NullableFailure) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableError) UnmarshalJSON(src []byte) error { +func (v *NullableFailure) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pinning/remote/client/openapi/model_error_error.go b/pinning/remote/client/openapi/model_failure_error.go similarity index 88% rename from pinning/remote/client/openapi/model_error_error.go rename to pinning/remote/client/openapi/model_failure_error.go index 0a177dbd2..4f38acdf9 100644 --- a/pinning/remote/client/openapi/model_error_error.go +++ b/pinning/remote/client/openapi/model_failure_error.go @@ -3,7 +3,7 @@ * * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 + * API version: 0.1.1 * Generated by: OpenAPI Generator (https://openapi-generator.tech) */ @@ -13,34 +13,34 @@ import ( "encoding/json" ) -// ErrorError struct for ErrorError -type ErrorError struct { +// 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"` } -// NewErrorError instantiates a new ErrorError object +// 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 NewErrorError(reason string) *ErrorError { - this := ErrorError{} +func NewFailureError(reason string) *FailureError { + this := FailureError{} this.Reason = reason return &this } -// NewErrorErrorWithDefaults instantiates a new ErrorError object +// 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 NewErrorErrorWithDefaults() *ErrorError { - this := ErrorError{} +func NewFailureErrorWithDefaults() *FailureError { + this := FailureError{} return &this } // GetReason returns the Reason field value -func (o *ErrorError) GetReason() string { +func (o *FailureError) GetReason() string { if o == nil { var ret string return ret @@ -51,7 +51,7 @@ func (o *ErrorError) GetReason() string { // GetReasonOk returns a tuple with the Reason field value // and a boolean to check if the value has been set. -func (o *ErrorError) GetReasonOk() (*string, bool) { +func (o *FailureError) GetReasonOk() (*string, bool) { if o == nil { return nil, false } @@ -59,12 +59,12 @@ func (o *ErrorError) GetReasonOk() (*string, bool) { } // SetReason sets field value -func (o *ErrorError) SetReason(v string) { +func (o *FailureError) SetReason(v string) { o.Reason = v } // GetDetails returns the Details field value if set, zero value otherwise. -func (o *ErrorError) GetDetails() string { +func (o *FailureError) GetDetails() string { if o == nil || o.Details == nil { var ret string return ret @@ -74,7 +74,7 @@ func (o *ErrorError) GetDetails() string { // 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 *ErrorError) GetDetailsOk() (*string, bool) { +func (o *FailureError) GetDetailsOk() (*string, bool) { if o == nil || o.Details == nil { return nil, false } @@ -82,7 +82,7 @@ func (o *ErrorError) GetDetailsOk() (*string, bool) { } // HasDetails returns a boolean if a field has been set. -func (o *ErrorError) HasDetails() bool { +func (o *FailureError) HasDetails() bool { if o != nil && o.Details != nil { return true } @@ -91,11 +91,11 @@ func (o *ErrorError) HasDetails() bool { } // SetDetails gets a reference to the given string and assigns it to the Details field. -func (o *ErrorError) SetDetails(v string) { +func (o *FailureError) SetDetails(v string) { o.Details = &v } -func (o ErrorError) MarshalJSON() ([]byte, error) { +func (o FailureError) MarshalJSON() ([]byte, error) { toSerialize := map[string]interface{}{} if true { toSerialize["reason"] = o.Reason @@ -106,38 +106,38 @@ func (o ErrorError) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -type NullableErrorError struct { - value *ErrorError +type NullableFailureError struct { + value *FailureError isSet bool } -func (v NullableErrorError) Get() *ErrorError { +func (v NullableFailureError) Get() *FailureError { return v.value } -func (v *NullableErrorError) Set(val *ErrorError) { +func (v *NullableFailureError) Set(val *FailureError) { v.value = val v.isSet = true } -func (v NullableErrorError) IsSet() bool { +func (v NullableFailureError) IsSet() bool { return v.isSet } -func (v *NullableErrorError) Unset() { +func (v *NullableFailureError) Unset() { v.value = nil v.isSet = false } -func NewNullableErrorError(val *ErrorError) *NullableErrorError { - return &NullableErrorError{value: val, isSet: true} +func NewNullableFailureError(val *FailureError) *NullableFailureError { + return &NullableFailureError{value: val, isSet: true} } -func (v NullableErrorError) MarshalJSON() ([]byte, error) { +func (v NullableFailureError) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableErrorError) UnmarshalJSON(src []byte) error { +func (v *NullableFailureError) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pinning/remote/client/openapi/model_pin.go b/pinning/remote/client/openapi/model_pin.go index 31ae0ca86..0152d43bb 100644 --- a/pinning/remote/client/openapi/model_pin.go +++ b/pinning/remote/client/openapi/model_pin.go @@ -3,7 +3,7 @@ * * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 + * API version: 0.1.1 * Generated by: OpenAPI Generator (https://openapi-generator.tech) */ diff --git a/pinning/remote/client/openapi/model_pin_results.go b/pinning/remote/client/openapi/model_pin_results.go index b569fe5df..eacb5e021 100644 --- a/pinning/remote/client/openapi/model_pin_results.go +++ b/pinning/remote/client/openapi/model_pin_results.go @@ -3,7 +3,7 @@ * * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 + * API version: 0.1.1 * Generated by: OpenAPI Generator (https://openapi-generator.tech) */ diff --git a/pinning/remote/client/openapi/model_pin_status.go b/pinning/remote/client/openapi/model_pin_status.go index 21d7992b2..0f44e62c2 100644 --- a/pinning/remote/client/openapi/model_pin_status.go +++ b/pinning/remote/client/openapi/model_pin_status.go @@ -3,7 +3,7 @@ * * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 + * API version: 0.1.1 * Generated by: OpenAPI Generator (https://openapi-generator.tech) */ diff --git a/pinning/remote/client/openapi/model_status.go b/pinning/remote/client/openapi/model_status.go index 7b30371ba..56944819f 100644 --- a/pinning/remote/client/openapi/model_status.go +++ b/pinning/remote/client/openapi/model_status.go @@ -3,7 +3,7 @@ * * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 + * API version: 0.1.1 * Generated by: OpenAPI Generator (https://openapi-generator.tech) */ diff --git a/pinning/remote/client/openapi/response.go b/pinning/remote/client/openapi/response.go index 5f1b37456..8f9fb0b08 100644 --- a/pinning/remote/client/openapi/response.go +++ b/pinning/remote/client/openapi/response.go @@ -3,7 +3,7 @@ * * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 + * API version: 0.1.1 * Generated by: OpenAPI Generator (https://openapi-generator.tech) */ diff --git a/pinning/remote/client/openapi/utils.go b/pinning/remote/client/openapi/utils.go index 976239127..25d36f11b 100644 --- a/pinning/remote/client/openapi/utils.go +++ b/pinning/remote/client/openapi/utils.go @@ -3,7 +3,7 @@ * * ## About this spec The IPFS Pinning Service API is intended to be an implementation-agnostic API: - 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\":}` - `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.0.5 + * API version: 0.1.1 * Generated by: OpenAPI Generator (https://openapi-generator.tech) */