# Blob storage service

Service for storing and retrieving blobs in object storage with workspace-based authorization.

OpenAPI file: [`nominal.blob_storage_service.v1.json`](https://dev.nominal.io/api/_downloads/b2756384ddc3232a48cc0ee653bb7091/nominal.blob_storage_service.v1.json)

## Endpoints

### Upload blob stream

POST `/blobs/v1`

Upload a blob using streaming. The blob will be stored with authorization checks based on the provided owningRid.

Body

`owningRid` [`ResourceIdentifier`](https://dev.nominal.io/api/rest/blob-storage-service.md#resourceidentifier) required
:   ​

    Fields of `ResourceIdentifier`

    `rid` string required
    :   Matches `^ri\.[a-z][a-z0-9\-]*\.([a-z0-9][a-z0-9\-]*)?\.[a-z][a-z0-9\-]*\.[a-zA-Z0-9\-\._]+$`.

`fileName` string required
:   ​

`ensureUnique` boolean required
:   when set to true, ensure_unique will attach the current timestamp to the file name this will ensure that we do not overwrite an existing file in blob storage

`content` string (base64) required
:   ​

Response

`fileName` string
:   This is the key that can be used in a retrieve blob request in order to retrieve this specific blob. If ensure_unique is not set, this will match the file name provided in UploadBlobStreamRequest

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/blobs/v1" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "owningRid": {
    "rid": "<rid>"
  },
  "fileName": "<file name>",
  "ensureUnique": true,
  "content": "<content>"
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/blobs/v1",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "owningRid": {"rid": "<rid>"},
        "fileName": "<file name>",
        "ensureUnique": True,
        "content": "<content>",
    },
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/blobs/v1",
    headers={"Authorization": "Bearer <api key>"},
    json={
        "owningRid": {"rid": "<rid>"},
        "fileName": "<file name>",
        "ensureUnique": True,
        "content": "<content>",
    },
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/blobs/v1",
            headers={"Authorization": "Bearer <api key>"},
            json={
                "owningRid": {"rid": "<rid>"},
                "fileName": "<file name>",
                "ensureUnique": True,
                "content": "<content>",
            },
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "fileName": "<file name>"
}
```

### Get signed URL for blob

POST `/blobs/v1/get`

Retrieve a signed URL for downloading a blob. The URL is valid for 15 minutes.

Body

`owningRid` [`ResourceIdentifier`](https://dev.nominal.io/api/rest/blob-storage-service.md#resourceidentifier) required
:   ​

    Fields of `ResourceIdentifier`

    `rid` string required
    :   Matches `^ri\.[a-z][a-z0-9\-]*\.([a-z0-9][a-z0-9\-]*)?\.[a-z][a-z0-9\-]*\.[a-zA-Z0-9\-\._]+$`.

`fileName` string required
:   ​

Response

`url` string
:   This is a short lived signed url that can be used by the client to retrieve the object

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/blobs/v1/get" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "owningRid": {
    "rid": "<rid>"
  },
  "fileName": "<file name>"
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/blobs/v1/get",
    headers={"Authorization": "Bearer <api key>"},
    json={"owningRid": {"rid": "<rid>"}, "fileName": "<file name>"},
)
response.raise_for_status()
print(response.json())
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/blobs/v1/get",
    headers={"Authorization": "Bearer <api key>"},
    json={"owningRid": {"rid": "<rid>"}, "fileName": "<file name>"},
)
response.raise_for_status()
print(response.json())
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/blobs/v1/get",
            headers={"Authorization": "Bearer <api key>"},
            json={"owningRid": {"rid": "<rid>"}, "fileName": "<file name>"},
        ) as response:
            response.raise_for_status()
            print(await response.json())

asyncio.run(main())
```

Response: `200`

```json
{
  "url": "<url>"
}
```

## Types

### ResourceIdentifier

This is used to identify any type of blob that will be in object storage.

`rid` string required
:   Matches `^ri\.[a-z][a-z0-9\-]*\.([a-z0-9][a-z0-9\-]*)?\.[a-z][a-z0-9\-]*\.[a-zA-Z0-9\-\._]+$`.

Page design based on [Scalar](https://scalar.com), MIT License.
