Skip to main content

DataJunction Python Client

This is a short introduction into the Python version of the DataJunction (DJ) client. For a full comprehensive intro into the DJ functionality please check out datajunction.io.

Installation

To install:

pip install datajunction

Intro

We have three top level client classes that help you choose the right path for your DataJunction actions.

  1. DJClient for basic read only access to metrics, dimensions, SQL and data.
  2. DJBuilder for those who would like to modify their DJ data model, build new nodes and/or modify the existing ones.
  3. DJAdmin for the administrators of the system to define the connections to your data catalog and engines.

DJ Client : Basic Access

Here you can see how to access and use the most common DataJunction features.

Examples

To initialize the client:

from datajunction import DJClient

dj = DJClient("http://localhost:8000")

NOTE If you are running in our demo docker environment please change the above URL to "http://dj:8000".

You are now connected to your DJ service and you can start looking around. Let's see what namespaces we have in the system:

dj.list_namespaces()

['default']

Next let's see what metrics and dimensions exist in the default namespace:

dj.list_metrics(namespace="default")

['default.num_repair_orders',
 'default.avg_repair_price',
 'default.total_repair_cost',
 'default.avg_length_of_employment',
 'default.total_repair_order_discounts',
 'default.avg_repair_order_discounts',
 'default.avg_time_to_dispatch']

dj.list_dimensions(namespace="default")

['default.date_dim',
 'default.repair_order',
 'default.contractor',
 'default.hard_hat',
 'default.local_hard_hats',
 'default.us_state',
 'default.dispatcher',
 'default.municipality_dim']

Now let's pick two metrics and see what dimensions they have in common:

dj.common_dimensions(
  metrics=["default.num_repair_orders", "default.total_repair_order_discounts"],
  name_only=True
)

['default.dispatcher.company_name',
 'default.dispatcher.dispatcher_id',
 'default.dispatcher.phone',
 'default.hard_hat.address',
 'default.hard_hat.birth_date',
 'default.hard_hat.city',
 ...

And finally let's ask DJ to show us some data for these metrics and some dimensions:

dj.data(
    metrics=["default.num_repair_orders", "default.total_repair_order_discounts"],
    dimensions=["default.hard_hat.city"]
)

| default_DOT_num_repair_orders	| default_DOT_total_repair_order_discounts | city        |
| ----------------------------- | ---------------------------------------- | ----------- |
| 4                             |                              5475.110138 | Jersey City |
| 3                             |                             11483.300049 | Billerica   |
| 5	                            |                              6725.170074 | Southgate   |
...

Reference

List of all available DJ client methods:

  • DJClient:

    list

    • list_namespaces( prefix: Optional[str])

    • list_dimensions( namespace: Optional[str])

    • list_metrics( namespace: Optional[str])

    • list_cubes( namespace: Optional[str])

    • list_sources( namespace: Optional[str])

    • list_transforms( namespace: Optional[str])

    • list_nodes( namespace: Optional[str], type_: Optional[NodeType])

    • list_nodes_with_tags( tag_names: List[str], node_type: Optional[NodeType])

    • list_catalogs()

    • list_engines()

    find

    • common_dimensions( metrics: List[str], name_only: bool = False)
    • common_metrics( dimensions: List[str], name_only: bool = False)

    execute

    • sql( metrics: List[str], dimensions: Optional[List[str]], filters: Optional[List[str]], engine_name: Optional[str], engine_version: Optional[str])
    • node_sql( node_name: str, dimensions: Optional[List[str]], filters: Optional[List[str]], engine_name: Optional[str], engine_version: Optional[str])
    • data( metrics: List[str], dimensions: Optional[List[str]], filters: Optional[List[str]], engine_name: Optional[str], engine_version: Optional[str], async_: bool = True)
    • node_data( node_name: str, dimensions: Optional[List[str]], filters: Optional[List[str]], engine_name: Optional[str], engine_version: Optional[str], async_: bool = True)

DJ Builder : Data Modelling

In this section we'll show you few examples to modify the DJ data model and its nodes.

Start Here

To initialize the DJ builder:

from datajunction import DJBuilder

djbuilder = DJBuilder("http://localhost:8000")

NOTE If you are running in our demo docker container please change the above URL to "http://dj:8000".

Namespaces

To access a namespace or check if it exists you can use the same simple call:

djbuilder.namespace("default")

Namespace(dj_client=..., namespace='default')
djbuilder.namespace("foo")

[DJClientException]: Namespace `foo` does not exist.

To create a namespace:

djbuilder.create_namespace("foo")

Namespace(dj_client=..., namespace='foo')

To delete (or restore) a namespace:

djbuilder.delete_namespace("foo")

djbuilder.restore_namespace("foo")

NOTE: The cascade parameter in both of above methods allows for cascading effect applied to all underlying nodes and namespaces. Use it with caution!

Tags

You can read existing tags as well as create new ones.

djbuilder.tag(name="deprecated", description="This node has been deprecated.", tag_type="standard", tag_metadata={"contact": "Foo Bar"})

Tag(dj_client=..., name='deprecated', description='This node has been deprecated.', tag_type='standard', tag_metadata={"contact": "Foo Bar"})
djbuilder.tag("official")

[DJClientException]: Tag `official` does not exist.

To create a tag:

djbuilder.create_tag(name="deprecated", description="This node has been deprecated.", tag_type="standard", tag_metadata={"contact": "Foo Bar"})

Tag(dj_client=..., name="deprecated", description="This node has been deprecated.", tag_type="standard", tag_metadata={"contact": "Foo Bar"})

To add a tag to a node:

repair_orders = djbuilder.source("default.repair_orders")
repair_orders.tags.append(djbuilder.tag("deprecated"))
repair_orders.save()

And to list the node names with a specific tag (or set of tags):

djbuilder.list_nodes_with_tags(tag_names=["deprecated"])  # works with DJClient() as well

["default.repair_orders"]

Nodes

To learn what Node means in the context of DJ, please check out this datajuntion.io page.

To list all (or some) nodes in the system you can use the list_<node-type>() methods described in the DJ Client : Basic Access section or you can use the namespace based method:

All nodes for a given namespace can be found with:

djbuilder.namespace("default").nodes()

Specific node types can be retrieved with:

djbuilder.namespace("default").sources()
djbuilder.namespace("default").dimensions()
djbuilder.namespace("default").metrics()
djbuilder.namespace("default").transforms()
djbuilder.namespace("default").cubes()

To create a source node:

repair_orders = djbuilder.create_source(
    name="repair_orders",
    display_name="Repair Orders",
    description="Repair orders",
    catalog="dj",
    schema_="roads",
    table="repair_orders",
)

Nodes can also be created in draft mode:

repair_orders = djbuilder.create_source(
    ...,
    mode=NodeMode.DRAFT
)

To create a dimension node:

repair_order = djbuilder.create_dimension(
    name="default.repair_order_dim",
    query="""
    SELECT
      repair_order_id,
      municipality_id,
      hard_hat_id,
      dispatcher_id
    FROM default.repair_orders
    """,
    description="Repair order dimension",
    primary_key=["repair_order_id"],
)

To create a transform node:

large_revenue_payments_only = djbuilder.create_transform(
    name="default.large_revenue_payments_only",
    query="""
    SELECT
      payment_id,
      payment_amount,
      customer_id,
      account_type
    FROM default.revenue
    WHERE payment_amount > 1000000
    """,
    description="Only large revenue payments",
)

To create a metric:

num_repair_orders = djbuilder.create_metric(
    name="default.num_repair_orders",
    query="""
    SELECT
      count(repair_order_id)
    FROM repair_orders
    """,
    description="Number of repair orders",
)

Reference

List of all available DJ builder methods:

  • DJBuilder:

    namespaces

    • namespace( namespace: str)
    • create_namespace( namespace: str)
    • delete_namespace(self, namespace: str, cascade: bool = False)
    • restore_namespace(self, namespace: str, cascade: bool = False)

    nodes

    • delete_node(self, node_name: str)
    • restore_node(self, node_name: str)

    nodes: source

    • source(self, node_name: str)
    • create_source( ..., mode: Optional[NodeMode] = NodeMode.PUBLISHED)
    • register_table( catalog: str, schema: str, table: str)
    • register_view( catalog: str, schema: str, view: str, query: str, replace: bool = False)

    nodes: transform

    • transform(self, node_name: str)
    • create_transform( ..., mode: Optional[NodeMode] = NodeMode.PUBLISHED)

    nodes: dimension

    • dimension(self, node_name: str)
    • create_dimension( ..., mode: Optional[NodeMode] = NodeMode.PUBLISHED)

    nodes: metric

    • metric(self, node_name: str)
    • create_metric( ..., mode: Optional[NodeMode] = NodeMode.PUBLISHED)

    nodes: cube

    • cube(self, node_name: str)
    • create_cube( ..., mode: Optional[NodeMode] = NodeMode.PUBLISHED)

DJ System Administration

In this section we'll describe how to manage your catalog and engines.

Start Here

To initialize the DJ admin:

from datajunction import DJAdmin

djadmin = DJAdmin("http://localhost:8000")

NOTE If you are running in our demo docker container please change the above URL to "http://dj:8000".

Examples

To list available catalogs:

djadmin.list_catalogs()

['warehouse']

To list available engines:

djadmin.list_engines()

[{'name': 'duckdb', 'version': '0.7.1'}]

To create a catalog:

djadmin.add_catalog(name="my-new-catalog")

To create a new engine:

djadmin.add_engine(
  name="Spark",
  version="3.2.1",
  uri="http:/foo",
  dialect="spark"
)

To linke an engine to a catalog:

djadmin.link_engine_to_catalog(
  engine="Spark", version="3.2.1", catalog="my-new-catalog"
)

Reference

List of all available DJ builder methods:

  • DJAdmin:

    Catalogs

    • list_catalogs() # in DJClient
    • get_catalog( name: str)
    • add_catalog( name: str)

    Engines

    • list_engines() # in DJClient
    • get_engine( name: str)
    • add_engine( name: str,version: str, uri: Optional[str], dialect: Optional[str])

    Together

    • link_engine_to_catalog( engine_name: str, engine_version: str, catalog: str)

Claude Code Integration

DataJunction provides comprehensive Claude Code integration through two components:

  1. MCP Tools - Live connectivity to your DJ instance for querying metrics, discovering dimensions, and visualizing data
  2. Skill - Passive knowledge about DataJunction concepts, patterns, and workflows

Both components are bundled with the Python client and can be installed with a single command.

What's Included

MCP Tools provide:

  • Query metrics and generate SQL
  • Discover available metrics and dimensions
  • Find common dimensions across metrics
  • Visualize data with inline charts

The DataJunction skill provides:

  • Core concepts - Star schema, dimension links, node types, and DJ fundamentals
  • Building the semantic layer - Creating metrics, dimensions, cubes, and dimension links
  • Repo-backed workflow - YAML node definitions, git workflow, and branch-based development

Installation

As a Claude Code plugin

If you use Claude Code, install the DJ plugin — it bundles the skills, the MCP server config, and the DJ subagent, and Claude Code manages it for you:

/plugin marketplace add DataJunction/dj
/plugin install datajunction@datajunction

The MCP tools run through the dj-mcp command from this package, so also pip install datajunction[mcp] and set DJ_API_URL to point at your instance if you want Claude to query live data.

With the DJ CLI

To copy the skills into your home directory and configure Claude Code (also the path for Claude Desktop):

dj setup-claude

This will:

  1. Copy the bundled skill to ~/.claude/skills/datajunction/
  2. Configure the DJ MCP server in your Claude config
  3. Make DataJunction expertise available to Claude in all your conversations

Options:

# Install only the skill (skip MCP server setup)
dj setup-claude --no-mcp

# Install only the MCP server (skip skill installation)
dj setup-claude --no-skills

After installation, restart Claude Code to load the changes.

Usage

Once installed, Claude Code will automatically use both MCP tools and the skill for DataJunction tasks:

MCP tools in action:

  • "Show me the revenue metric" → Queries your live DJ instance
  • "What dimensions are available for these metrics?" → Discovers common dimensions
  • "Visualize revenue by city" → Generates and displays inline charts

Skill in action:

  • "How do dimension links work in DataJunction?" → Explains concepts
  • "How do I create a metric in YAML?" → Shows YAML examples and patterns
  • "Explain the repo-backed workflow" → Details git-based development

The MCP tools provide live data access while the skill provides conceptual knowledge and best practices.

Customizing for Your Organization

If you need organization-specific skill content:

Option A: Fork the client

  1. Fork datajunction-clients/python
  2. Modify datajunction/skills/datajunction.md with your custom content
  3. Publish your custom client package

Option B: Override after install

  1. Run dj setup-claude to get the base skill
  2. Manually edit ~/.claude/skills/datajunction/SKILL.md with your customizations

Skill Location

The skill file is bundled at:

datajunction/skills/datajunction.md

And installed to:

~/.claude/skills/datajunction/SKILL.md

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

datajunction-0.0.198.tar.gz (148.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

datajunction-0.0.198-py3-none-any.whl (105.7 kB view details)

Uploaded Python 3

File details

Details for the file datajunction-0.0.198.tar.gz.

File metadata

  • Download URL: datajunction-0.0.198.tar.gz
  • Upload date:
  • Size: 148.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for datajunction-0.0.198.tar.gz
Algorithm Hash digest
SHA256 9be81200ba6c4c0385537e425f0ce79d3646d7001becf1108f48dbef26fff146
MD5 1471e12008782c020f72d4e4a5db99ef
BLAKE2b-256 d292384777e4fddab042ca22395b0735602e7e442b576a89672d6389f7cc5490

See more details on using hashes here.

Provenance

The following attestation bundles were made for datajunction-0.0.198.tar.gz:

Publisher: publish.yml on DataJunction/dj

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file datajunction-0.0.198-py3-none-any.whl.

File metadata

  • Download URL: datajunction-0.0.198-py3-none-any.whl
  • Upload date:
  • Size: 105.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for datajunction-0.0.198-py3-none-any.whl
Algorithm Hash digest
SHA256 418f0d9dba89fcf7781a73958dd0abe7556567f437b7d5bc6f2a830aaf3d96a5
MD5 56cdc1ebde61bb4bea79edf3c8112693
BLAKE2b-256 3d399c627f516ebedbccf2543a1e276a3171d80d52297fd0ea49a502bb1e7cf5

See more details on using hashes here.

Provenance

The following attestation bundles were made for datajunction-0.0.198-py3-none-any.whl:

Publisher: publish.yml on DataJunction/dj

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.0.217

2 files

0.0.216

2 files

0.0.215

2 files

0.0.214

2 files

0.0.213

2 files

0.0.212

2 files

0.0.211

2 files

0.0.210

2 files

0.0.209

2 files

0.0.208

2 files

0.0.207

2 files

0.0.206

2 files

0.0.205

2 files

0.0.204

2 files

0.0.203

2 files

0.0.202

2 files

0.0.201

2 files

0.0.200

2 files

0.0.199

2 files

This release

0.0.198 This release

2 files

0.0.197

2 files

0.0.196

2 files

0.0.195

2 files

0.0.194

2 files

0.0.193

2 files

0.0.192

2 files

0.0.191

2 files

0.0.190

2 files

0.0.189

2 files

0.0.188

2 files

0.0.187

2 files

0.0.186

2 files

0.0.185

2 files

0.0.184

2 files

0.0.183

2 files

0.0.182

2 files

0.0.181

2 files

0.0.180

2 files

0.0.179

2 files

0.0.178

2 files

0.0.177

2 files

0.0.176

2 files

0.0.175

2 files

0.0.174

2 files

0.0.173

2 files

0.0.172

2 files

0.0.171

2 files

0.0.170

2 files

0.0.169

2 files

0.0.168

2 files

0.0.167

2 files

0.0.166

2 files

0.0.165

2 files

0.0.164

2 files

0.0.163

2 files

0.0.162

2 files

0.0.161

2 files

0.0.160

2 files

0.0.159

2 files

0.0.158

2 files

0.0.157

2 files

0.0.156

2 files

0.0.155

2 files

0.0.154

2 files

0.0.153

2 files

0.0.152

2 files

0.0.151

2 files

0.0.150

2 files

0.0.149

2 files

0.0.148

2 files

0.0.147

2 files

0.0.146

2 files

0.0.145

2 files

0.0.144

2 files

0.0.143

2 files

0.0.142

2 files

0.0.141

2 files

0.0.140

2 files

0.0.139

2 files

0.0.138

2 files

0.0.137

2 files

0.0.136

2 files

0.0.135

2 files

0.0.134

2 files

0.0.133

2 files

0.0.132

2 files

0.0.131

2 files

0.0.130

2 files

0.0.129

2 files

0.0.128

2 files

0.0.127

2 files

0.0.126

2 files

0.0.125

2 files

0.0.124

2 files

0.0.123

2 files

0.0.122

2 files

0.0.121

2 files

0.0.120

2 files

0.0.119

2 files

0.0.118

2 files

0.0.117

2 files

0.0.116

2 files

0.0.115

2 files

0.0.114

2 files

0.0.113

2 files

0.0.112

2 files

0.0.111

2 files

0.0.110

2 files

0.0.109

2 files

0.0.108

2 files

0.0.107

2 files

0.0.106

2 files

0.0.105

2 files

0.0.104

2 files

0.0.103

2 files

0.0.102

2 files

0.0.101

2 files

0.0.100

2 files

0.0.99

2 files

0.0.98

2 files

0.0.97

2 files

0.0.96

2 files

0.0.95

2 files

0.0.94

2 files

0.0.93

2 files

0.0.92

2 files

0.0.91

2 files

0.0.90

2 files

0.0.89

2 files

0.0.88

2 files

0.0.87

2 files

0.0.86

2 files

0.0.85

2 files

0.0.84

2 files

0.0.83

2 files

0.0.82

2 files

0.0.81

2 files

0.0.80

2 files

0.0.79

2 files

0.0.78

2 files

0.0.77

2 files

0.0.76

2 files

0.0.75

2 files

0.0.74

2 files

0.0.72

2 files

0.0.71

2 files

0.0.70

2 files

0.0.69

2 files

0.0.68

2 files

0.0.67

2 files

0.0.66

2 files

0.0.65

2 files

0.0.64

2 files

0.0.63

2 files

0.0.62

2 files

0.0.61

2 files

0.0.59

2 files

0.0.58

2 files

0.0.57

2 files

0.0.56

2 files

0.0.55

2 files

0.0.54

2 files

0.0.53

2 files

0.0.52

2 files

0.0.51

2 files

0.0.50

2 files

0.0.49

2 files

0.0.48

2 files

0.0.47

2 files

0.0.46

2 files

0.0.45

2 files

0.0.44

2 files

0.0.43

2 files

0.0.42

2 files

0.0.41

2 files

0.0.40

2 files

0.0.39

2 files

0.0.38

2 files

0.0.37

2 files

0.0.36

2 files

0.0.35

2 files

0.0.34

2 files

0.0.33

2 files

0.0.32

2 files

0.0.31

2 files

0.0.30

2 files

0.0.29

2 files

0.0.28

2 files

0.0.27

2 files

0.0.26

2 files

0.0.25

2 files

0.0.24

2 files

0.0.23

2 files

0.0.22

2 files

0.0.21

2 files

0.0.20

2 files

0.0.19

2 files

0.0.18

2 files

0.0.17

2 files

0.0.16

2 files

0.0.15

2 files

0.0.14

2 files

0.0.13

2 files

0.0.12

2 files

0.0.11

2 files

0.0.10

2 files

0.0.9

2 files

0.0.8

2 files

0.0.7

2 files

0.0.6

2 files

0.0.5

2 files

0.0.4

2 files

0.0.3

2 files

0.0.2

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page