Skip to content

Python SDK

github | pypi

The official Python client for JsonBank. Requires Python 3.9+.

Installation

shell
pip install jsonbank

Initialize

JsonBank can be initialized with or without api keys.
Api Keys are only required when you want to access private/secured documents

python
from jsonbank import JsonBank

jsb = JsonBank()
python
from jsonbank import JsonBank

# Initialize with Api keys.
jsb = JsonBank(
    public_key="JSB_PUBLIC_KEY",
    private_key="JSB_PRIVATE_KEY",
)

# authenticate the api keys
jsb.authenticate()

Public Api Key

A read-only key. Use it to authenticate() and to read your own private documents. Public documents need no key at all.

Private Api Key

A write-only key, only needed to create, update or delete documents.

Check Authentication

To check if the user is authenticated, use the is_authenticated method.
Make sure to have called authenticate method before.

python
jsb.authenticate()

# check if the user is authenticated
jsb.is_authenticated()  # True

Public Content Methods

Public contents do not require authentication.

get_document_meta()

Get a public document meta details either by id or path. Does not return the content of the document. To get the content, use get_content method.

python
meta = jsb.get_document_meta("jsonbank/sdk-test/index.json")
# meta is a DocumentMeta object
print(meta.id)            # id of the document
print(meta.project)       # project name
print(meta.name)          # name of the document
print(meta.content_size)  # size of the document
print(meta.path)          # path of the document
print(meta.updated_at)    # last update time
print(meta.created_at)    # creation time
python
@dataclass
class DocumentMeta:
    id: str
    project: str
    path: str
    name: str
    content_size: ContentSize
    created_at: str
    updated_at: str
    folder_id: Optional[str] = None

@dataclass
class ContentSize:
    number: int
    string: str

get_content()

Get a public document content either by id or path. It returns the parsed json (a dict or list).

python
data = jsb.get_content("jsonbank/sdk-test/index.json")
print(data["author"])  # jsonbank
json
{
  "name": "JsonBank SDK Test File",
  "author": "jsonbank"
}

get_content_as_string()

Get a public document content either by id or path as a string. It returns the raw json string.

python
data = jsb.get_content_as_string("jsonbank/sdk-test/index.json")
# data is a string

get_github_content()

Get a public json file from Github. This will read from the default branch of the repo.
It returns the parsed json.

Note: Referenced file must be a public json file.
python
data = jsb.get_github_content("org/repo/file.json")

# example
result = jsb.get_github_content("jsonbankio/documentation/github-test.json")

get_github_content_as_string()

Same as get_github_content but returns the content as a string.

Note: Referenced file must be a public json file.
python
data = jsb.get_github_content_as_string("org/repo/file.json")

# example
result = jsb.get_github_content_as_string("jsonbankio/documentation/github-test.json")

Access Own Content

Your own content is the documents in your projects. To read them, initialize with your api keys and authenticate first. See With Api Keys for more details.

Note: These methods need your public api key. Call authenticate() before using them.

get_own_content()

Get one of your documents either by id or path. Works for private documents too. It returns the parsed json.

python
data = jsb.get_own_content("sdk-test/index.json")
# data is a dict (or list)

get_own_content_as_string()

Same as get_own_content but returns the raw json string.

python
data = jsb.get_own_content_as_string("sdk-test/index.json")
# data is a string

get_own_document_meta()

Get the meta of one of your documents either by id or path. Returns the same DocumentMeta as get_document_meta.

python
meta = jsb.get_own_document_meta("sdk-test/index.json")

has_own_document()

Check if one of your documents exists, either by id or path.

python
jsb.has_own_document("sdk-test/index.json")  # True
jsb.has_own_document("does-not-exist")       # False
Note: Returns False instead of raising when the document is not found.

Managing Content

Create, update and delete documents in your projects.

Note: These methods need your private api key.

create_document()

Create a new document in a project. folder is optional, leave it out to create at the project root. content can be a dict, list, or a json string.

python
doc = jsb.create_document(
    name="new_doc.json",
    project="sdk-test",
    folder="folder",  # optional
    content={"name": "new_doc", "author": "jsonbank"},
)
python
@dataclass
class NewDocument:
    id: str
    name: str
    path: str
    project: str
    created_at: str
    exists: bool = False

create_document_if_not_exists()

Same as create_document, but if the document already exists it is fetched and returned instead of raising.

python
doc = jsb.create_document_if_not_exists(
    name="index.json",
    project="sdk-test",
    content={"name": "JsonBank SDK Test File", "author": "jsonbank"},
)

# when it already existed
doc.exists  # True

update_own_document()

Update the content of one of your documents either by id or path. content can be a dict, list, or a json string.

python
result = jsb.update_own_document("sdk-test/index.json", {
    "name": "JsonBank SDK Test File",
    "author": "jsonbank",
    "updated": True,
})

result.changed  # True
python
@dataclass
class UpdatedDocument:
    changed: bool

delete_document()

Delete one of your documents either by id or path.

python
jsb.delete_document("sdk-test/folder/new_doc.json")
# -> DeletedDocument(deleted=True)
Note: Returns deleted=False instead of raising when the document is not found.

Folders

Group documents into folders inside a project.

get_folder()

Get a folder either by id or path.

python
folder = jsb.get_folder("sdk-test/folder")
python
@dataclass
class Folder:
    id: str
    name: str
    path: str
    project: str
    created_at: str
    updated_at: str
    stats: Optional[FolderStats] = None

@dataclass
class FolderStats:
    documents: int
    folders: int

get_folder_with_stats()

Same as get_folder but also fills in stats (how many documents and folders are inside).

python
folder = jsb.get_folder_with_stats("sdk-test/folder")

print(folder.stats.documents)
print(folder.stats.folders)

create_folder()

Create a new folder in a project. folder is optional, use it to nest inside another folder.

python
folder = jsb.create_folder(
    name="folder",
    project="sdk-test",
)

create_folder_if_not_exists()

Same as create_folder, but if the folder already exists it is fetched and returned instead of raising.

python
folder = jsb.create_folder_if_not_exists(
    name="folder",
    project="sdk-test",
)

# when it already existed
folder.exists  # True

Listing

Browse what is inside a project, one level deep. Use these when you do not already know the ids or paths of your documents and folders.

Note: These methods need your public api key. Call authenticate() before using them.

scan_project()

List the documents and folders of a project together. Leave the options out to list the project root, or pass folder to list inside a folder.

python
listing = jsb.scan_project("sdk-test")

print(listing.project.slug)          # sdk-test
print(len(listing.documents.data))   # documents on this page
print(listing.documents.meta.total)  # documents in total
print(len(listing.folders.data))     # folders on this page
python
@dataclass
class ScanProjectResponse:
    project: ListedProject
    documents: PaginatedDocuments
    folders: PaginatedFolders
    # None when the project root was listed
    folder: Optional[ListedFolder] = None

@dataclass
class ListedProject:
    slug: str
    title: str
    access: str

@dataclass
class ListedFolder:
    id: str
    name: str
    path: str
    parent_folder: Optional[str] = None

@dataclass
class PaginatedDocuments:
    data: List[DocumentMeta]
    meta: PaginationMeta

@dataclass
class PaginatedFolders:
    data: List[Folder]
    meta: PaginationMeta

@dataclass
class PaginationMeta:
    page: int
    per_page: int
    total: int
    last_page: int

Each entry in documents.data is a DocumentMeta and each entry in folders.data is a Folder.

To scan inside a folder, pass its id or its path. The folder you asked for comes back as listing.folder.

python
listing = jsb.scan_project("sdk-test", folder="folder")

print(listing.folder.path)  # folder
Note:folder is only set when you asked for one. It is None when the project root was listed.

list_documents()

Same as scan_project without the folders, so nothing you do not need is queried or paged. Content is not included, fetch it with get_own_content.

python
listing = jsb.list_documents("sdk-test", per_page=50)

for doc in listing.documents.data:
    print(doc.path, doc.content_size.string)
python
@dataclass
class ListDocumentsResponse:
    project: ListedProject
    documents: PaginatedDocuments
    folder: Optional[ListedFolder] = None

list_folders()

Same as scan_project without the documents.

python
listing = jsb.list_folders("sdk-test", sort="createdAt", order="desc")

for folder in listing.folders.data:
    print(folder.path)
python
@dataclass
class ListFoldersResponse:
    project: ListedProject
    folders: PaginatedFolders
    folder: Optional[ListedFolder] = None

Listing options

All options are keyword-only and optional. Leave one out and the server default is used.

list_documents and list_folders return a single list, so they take a single page and per_page:

  • folder: folder id or path to list inside. Leave it out to list the project root.
  • page: page to return. Defaults to 1.
  • per_page: results per page, up to 1000. Defaults to 100.
  • sort: field to sort by, one of "name" (default), "createdAt" or "updatedAt".
  • order: "asc" (default) or "desc".

scan_project returns two lists that paginate independently, so it takes a page and a size for each:

  • folder, sort, order: same as above, sort and order apply to both lists.
  • documents_page, documents_per_page: pagination of the documents list.
  • folders_page, folders_per_page: pagination of the folders list.
Note:sort and order are typed as Literal, so your editor will autocomplete the accepted values.

Paginating

Each list is a single page. Read meta.last_page to know how many there are and walk them:

python
page, last_page = 1, 1

while page <= last_page:
    listing = jsb.list_documents("sdk-test", page=page, per_page=1000)
    last_page = listing.documents.meta.last_page

    for doc in listing.documents.data:
        print(doc.path)

    page += 1

Uploading Files

Upload a json file straight from your file system.

upload_document()

Reads a file from disk and creates a document from it. name and folder are optional, name defaults to the file name.

python
doc = jsb.upload_document(
    file_path="./upload.json",
    project="sdk-test",
    folder="folder",  # optional
)
python
@dataclass
class NewDocument:
    id: str
    name: str
    path: str
    project: str
    created_at: str
    exists: bool = False

Error Handling

Methods raise a JsonBankError when something goes wrong. It has a code you can check.

python
from jsonbank import JsonBankError

try:
    jsb.create_folder(name="folder", project="sdk-test")
except JsonBankError as e:
    if e.code == "name.exists":
        # folder already exists, ignore it or fetch it instead
        pass
    else:
        raise

Common error codes:

  • notFound: the document or folder does not exist.
  • name.exists: a document or folder with that name already exists.
Note: Some methods don't raise, they return a value instead: has_own_document() returns False, delete_document() returns deleted=False, and the ..._if_not_exists() methods return the existing item with exists=True.

Next steps