Python SDK
The official Python client for JsonBank. Requires Python 3.9+.
Installation
pip install jsonbankInitialize
JsonBank can be initialized with or without api keys.
Api Keys are only required when you want to access private/secured documents
from jsonbank import JsonBank
jsb = JsonBank()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.
jsb.authenticate()
# check if the user is authenticated
jsb.is_authenticated() # TruePublic 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.
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@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: strget_content()
Get a public document content either by id or path. It returns the parsed json (a dict or list).
data = jsb.get_content("jsonbank/sdk-test/index.json")
print(data["author"]) # jsonbank{
"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.
data = jsb.get_content_as_string("jsonbank/sdk-test/index.json")
# data is a stringget_github_content()
Get a public json file from Github. This will read from the default branch of the repo.
It returns the parsed json.
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.
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.
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.
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.
data = jsb.get_own_content_as_string("sdk-test/index.json")
# data is a stringget_own_document_meta()
Get the meta of one of your documents either by id or path. Returns the same DocumentMeta as get_document_meta.
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.
jsb.has_own_document("sdk-test/index.json") # True
jsb.has_own_document("does-not-exist") # FalseFalse instead of raising when the document is not found. Managing Content
Create, update and delete documents in your projects.
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.
doc = jsb.create_document(
name="new_doc.json",
project="sdk-test",
folder="folder", # optional
content={"name": "new_doc", "author": "jsonbank"},
)@dataclass
class NewDocument:
id: str
name: str
path: str
project: str
created_at: str
exists: bool = Falsecreate_document_if_not_exists()
Same as create_document, but if the document already exists it is fetched and returned instead of raising.
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 # Trueupdate_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.
result = jsb.update_own_document("sdk-test/index.json", {
"name": "JsonBank SDK Test File",
"author": "jsonbank",
"updated": True,
})
result.changed # True@dataclass
class UpdatedDocument:
changed: booldelete_document()
Delete one of your documents either by id or path.
jsb.delete_document("sdk-test/folder/new_doc.json")
# -> DeletedDocument(deleted=True)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.
folder = jsb.get_folder("sdk-test/folder")@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: intget_folder_with_stats()
Same as get_folder but also fills in stats (how many documents and folders are inside).
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.
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.
folder = jsb.create_folder_if_not_exists(
name="folder",
project="sdk-test",
)
# when it already existed
folder.exists # TrueListing
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.
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.
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@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: intEach 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.
listing = jsb.scan_project("sdk-test", folder="folder")
print(listing.folder.path) # folderfolder 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.
listing = jsb.list_documents("sdk-test", per_page=50)
for doc in listing.documents.data:
print(doc.path, doc.content_size.string)@dataclass
class ListDocumentsResponse:
project: ListedProject
documents: PaginatedDocuments
folder: Optional[ListedFolder] = Nonelist_folders()
Same as scan_project without the documents.
listing = jsb.list_folders("sdk-test", sort="createdAt", order="desc")
for folder in listing.folders.data:
print(folder.path)@dataclass
class ListFoldersResponse:
project: ListedProject
folders: PaginatedFolders
folder: Optional[ListedFolder] = NoneListing 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
idorpathto 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 to100. - 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,
sortandorderapply to both lists. - documents_page, documents_per_page: pagination of the documents list.
- folders_page, folders_per_page: pagination of the folders list.
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:
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 += 1Uploading 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.
doc = jsb.upload_document(
file_path="./upload.json",
project="sdk-test",
folder="folder", # optional
)@dataclass
class NewDocument:
id: str
name: str
path: str
project: str
created_at: str
exists: bool = FalseError Handling
Methods raise a JsonBankError when something goes wrong. It has a code you can check.
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:
raiseCommon error codes:
notFound: the document or folder does not exist.name.exists: a document or folder with that name already exists.
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
- Concepts: projects, paths, public vs private, and the key model.
- Webhooks: get notified when your documents change.
- Browse the other SDKs