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 ​