Practicing with our Python SDK¶
We also have a Python SDK if that's your language of choice. Start by following the steps above under Configuration.
Most systems already have python version 3 installed, available directly through the python command. Make sure by typing the following:
You should see something similar to this:
If not, you'll need to install it. The official Python documentation provides downloadable installations.
First, create a new folder to hold you project:
Next, create and activate a virtual environment.
This creates a virtual environment. Note: If you get an error message regarding "ensurepip not being available" type the following to add the python3-venv package:
and then repeat the python3 -m venv venv
command.
Now activate the virtual environment. On Mac and Linux, type:
Now install the GolemBase SDK and some additional libraries you'll need:
Code to create a private.key file¶
Now we'll create a python app that can create a wallet stored in a private.key
file. Create a file called wallet.py
and add the following to it:
import os
from eth_account import Account
key_path = 'private.key'
if os.path.exists(key_path):
print(f'File "{key_path}" already exists. Aborting.')
exit(0)
acct = Account.create()
with open(key_path, 'wb') as f:
f.write(bytes.fromhex(acct.key.hex()))
print('Address:', acct.address)
Then run the above by typing:
You should see output similar to the following:
This is the address portion of the private key you just created. Copy this to your clipboard, as you'll need it in the next step.
Adding Funds¶
Open your browser and go to this link, which is the for Kaolin:
https://kaolin.holesky.golem-base.io/faucet/
Paste your account Address in and click Request Funds. After a moment, your account will have a couple Eth available in our testnet.
Creating entities in Golem-base¶
Now create a file called main.py and insert the following into it:
"""GolemBase Python SDK."""
import argparse
import asyncio
import logging
import logging.config
import anyio
from golem_base_sdk import (
Annotation,
GolemBaseClient,
GolemBaseCreate,
GolemBaseDelete,
GolemBaseExtend,
GolemBaseUpdate,
)
logging.config.dictConfig(
{
"version": 1,
"formatters": {
"default": {
"format": "[%(asctime)s] %(levelname)s in %(module)s: %(message)s",
}
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"formatter": "default",
"level": "DEBUG",
"stream": "ext://sys.stdout",
}
},
"loggers": {
# "": {"level": "DEBUG", "handlers": ["console"]},
"": {"level": "INFO", "handlers": ["console"]},
},
# Avoid pre-existing loggers from imports being disabled
"disable_existing_loggers": False,
}
)
logger = logging.getLogger(__name__)
INSTANCE_URLS = {
"demo": {
"rpc": "https://api.golembase.demo.golem-base.io",
},
"local": {
"rpc": "http://localhost:8545",
"ws": "ws://localhost:8545",
},
"kaolin": {
"rpc": "https://rpc.kaolin.holesky.golem-base.io",
"ws": "wss://ws.rpc.kaolin.holesky.golem-base.io",
},
}
async def run_example(instance: str) -> None: # noqa: PLR0915
"""Run the example."""
async with await anyio.open_file(
"./private.key",
"rb",
) as private_key_file:
key_bytes = await private_key_file.read(32)
client = await GolemBaseClient.create(
rpc_url=INSTANCE_URLS[instance]["rpc"],
ws_url=INSTANCE_URLS[instance]["ws"],
private_key=key_bytes,
)
watch_logs_handle = await client.watch_logs(
label="first",
create_callback=lambda create: logger.info(
"""\n
Got create event: %s
""",
create,
),
update_callback=lambda update: logger.info(
"""\n
Got update event: %s
""",
update,
),
)
await client.watch_logs(
label="second",
delete_callback=lambda deleted_key: logger.info(
"""\n
Got delete event: %s
""",
deleted_key,
),
extend_callback=lambda extension: logger.info(
"""\n
Got extend event: %s
""",
extension,
),
)
if await client.is_connected():
logger.info("""\n
*****************************
* Checking basic methods... *
*****************************
""")
block = await client.http_client().eth.get_block("latest")
logger.info("Retrieved block %s", block["number"])
logger.info("entity count: %s", await client.get_entity_count())
logger.info("""\n
*************************
* Creating an entity... *
*************************
""")
create_receipt = await client.create_entities(
[GolemBaseCreate(b"hello", 60, [Annotation("app", "demo")], [])]
)
entity_key = create_receipt[0].entity_key
logger.info("receipt: %s", create_receipt)
logger.info("entity count: %s", await client.get_entity_count())
logger.info("created entity with key %s", entity_key)
logger.info("storage value: %s", await client.get_storage_value(entity_key))
metadata = await client.get_entity_metadata(entity_key)
logger.info("entity metadata: %s", metadata)
logger.info("""\n
***********************************
* Extend the BTL of the entity... *
***********************************
""")
logger.info(
"entities to expire at block %s: %s",
metadata.expires_at_block,
await client.get_entities_to_expire_at_block(metadata.expires_at_block),
)
[extend_receipt] = await client.extend_entities(
[GolemBaseExtend(entity_key, 60)]
)
logger.info("receipt: %s", extend_receipt)
logger.info(
"entities to expire at block %s: %s",
metadata.expires_at_block,
await client.get_entities_to_expire_at_block(metadata.expires_at_block),
)
logger.info(
"entities to expire at block %s: %s",
extend_receipt.new_expiration_block,
await client.get_entities_to_expire_at_block(
extend_receipt.new_expiration_block
),
)
logger.info("entity metadata: %s", await client.get_entity_metadata(entity_key))
logger.info("""\n
************************
* Update the entity... *
************************
""")
logger.info(
"block number: %s", await client.http_client().eth.get_block_number()
)
[update_receipt] = await client.update_entities(
[GolemBaseUpdate(entity_key, b"hello", 60, [Annotation("app", "demo")], [])]
)
logger.info("receipt: %s", update_receipt)
entity_key = update_receipt.entity_key
logger.info("entity metadata: %s", await client.get_entity_metadata(entity_key))
logger.info("""\n
*************************
* Query for entities... *
*************************
""")
query_result = await client.query_entities('app = "demo"')
logger.info("Query result: %s", query_result)
logger.info("""\n
************************
* Delete the entity... *
************************
""")
logger.info("entity metadata: %s", await client.get_entity_metadata(entity_key))
logger.info(
"block number: %s", await client.http_client().eth.get_block_number()
)
receipt = await client.delete_entities([GolemBaseDelete(entity_key)])
logger.info("receipt: %s", receipt)
logger.info(
"My entities: %s",
await client.get_entities_of_owner(client.get_account_address()),
)
logger.info(
"All entities: %s",
await client.get_all_entity_keys(),
)
await watch_logs_handle.unsubscribe()
logger.info("""\n
*********************************************
* Creating an entity to test unsubscribe... *
*********************************************
""")
create_receipt = await client.create_entities(
[GolemBaseCreate(b"hello", 60, [Annotation("app", "demo")], [])]
)
entity_key = create_receipt[0].entity_key
logger.info("receipt: %s", create_receipt)
logger.info("entity count: %s", await client.get_entity_count())
logger.info("created entity with key %s", entity_key)
logger.info("storage value: %s", await client.get_storage_value(entity_key))
metadata = await client.get_entity_metadata(entity_key)
logger.info("entity metadata: %s", metadata)
await client.delete_entities([GolemBaseDelete(entity_key)])
else:
logger.warning("Could not connect to the API...")
await client.disconnect()
def main() -> None:
"""Run the example."""
parser = argparse.ArgumentParser(description="GolemBase Python SDK Example")
parser.add_argument(
"--instance",
choices=INSTANCE_URLS.keys(),
default="kaolin",
help="Which instance to connect to (default: kaolin)",
)
args = parser.parse_args()
logger.info("Starting main loop")
asyncio.run(run_example(args.instance))
if __name__ == "__main__":
main()
Note that this example includes a command line option to choose between different nodes:
-
A local node running in a container
-
Our testnet server
The testnet server is the default, which is what we want. So run the file by simply typing:
To see more examples and learn about our Python SDK, visit our Python SDK's repo on GitHub.
-
Wish to learn more?
Golem Base introduces a novel architectural model for decentralized data infrastructure — designed to be modular, Ethereum-native, and accessible across both Web2 and Web3.
For a complete overview:
Read the Litepaper (PDF)It covers:
- The structure and role of DB-Chains
- How Golem Base aligns with Ethereum Layer 2/3 philosophy
- Potential real-world use cases
Golem Base OriginsGolem Base was born from a need inside Golem Network — and grew into its own thing. Built by an independent team committed to the idea that data autonomy should be the norm, not the exception. Read more
-
Join the Community
Stay connected and get help as you explore Golem Base.
- Discord — Chat with the team and other developers in real time.
- GitHub — Ask questions, share feedback, or explore new ideas.
- Twitter (X) — Follow us for announcements, updates, and ecosystem highlights.
- Blog — Read technical deep dives, tutorials, and project news.
Need Help?
- Start with the Getting Started guide.
- Browse the FAQ (coming soon).
- Or open an issue on GitHub.