Python quick start

August 7, 2026 ยท View on GitHub

TypeBridge applications author schema in Split-YAML and import generated Python bindings. The generated package owns attribute values, entity and relation models, concise managers, and immutable query tokens.

1. Create the workspace

Create typebridge.yaml:

format: typebridge.workspace/v1

schema:
  root: schema/schema.yaml
  ownership: exclusive
  managed-scope: quickstart

compatibility:
  semantic-profile: typedb-3.12.1/v1

migrations:
  directory: migrations/v2
  app-label: quickstart
  destructive: require-approval

bindings:
  python:
    output: app_models

environments:
  development:
    database: quickstart
    uri: localhost:1729
    tls: 'false'
    migrate: 'true'
    credential:
      username: env:TYPEDB_USERNAME
      password: env:TYPEDB_PASSWORD

Create schema/schema.yaml:

format: typebridge.schema-set/v1
sources: [application.yaml]

Create schema/application.yaml:

format: typebridge.schema/v2

attributes:
  person-id: {value: string}
  age: {value: integer}
  company-id: {value: string}

entities:
  person:
    owns:
      person-id: {key: true}
      age: {card: {min: 0, max: 1}}
  company:
    owns:
      company-id: {key: true}

relations:
  employment:
    relates:
      employee: {card: 1}
      employer: {card: 1}

plays:
  person:
    employment: [employee]
  company:
    employment: [employer]

2. Check, migrate, and generate

type-bridge --manifest typebridge.yaml schema check
type-bridge --manifest typebridge.yaml schema generate
type-bridge --manifest typebridge.yaml migration make --name initial
type-bridge --manifest typebridge.yaml migration apply --environment development

schema check is offline. Migration application is the explicit database change; generation never mutates TypeDB. The generated Python package privately embeds the verified authority used by its managers and query sessions, so this ordinary application path does not configure, generate, or read an external JSON authority. Commit the workspace and migration history, and regenerate all outputs after an accepted schema change. Set TYPEDB_USERNAME and TYPEDB_PASSWORD for the named TypeDB environment before running the connected apply command.

3. Put and filter one type

from app_models import Age, Person, PersonId
from type_bridge import Database

db = Database(address="localhost:1729", database="quickstart")
db.connect()

ada = Person(person_id=PersonId("ada"), age=Age(36))
Person.manager(db).put(ada)

adults = Person.manager(db).filter(age__gte=18).all()
for person in adults:
    print(person.person_id.value, person.age.value if person.age else None)

put is idempotent for the generated model's declared key. Managers also provide insert, insert_many, put_many, update, delete, get_by_iid, all, first, count, and exists. Pass a database for an owned transaction or an existing transaction for an atomic multi-operation workflow.

4. Insert a relation

from app_models import Company, CompanyId, Employment

acme = Company(company_id=CompanyId("acme"))
Company.manager(db).put(acme)

employment = Employment(employee=ada, employer=acme)
Employment.manager(db).insert(employment)

Generated relation constructors accept only projected player types allowed by the Split-YAML plays facts. Hydrated relations preserve their concrete player types and IIDs.

5. Query across types

from app_models import Employment

session = Person.query(db)
person = session.exact(Person)
employment = session.exact(Employment)

employee = employment.role(Employment.employee).connects(person)
rows = (
    session.query(person, employment)
    .where(employee, person.field(Person.age).gte(Age(18)))
    .rows(limit=100)
)

Use exact for one generated type and subtypes for a polymorphic binding. The package-local query API supports owner-aware fields and roles, Boolean and string predicates, bounded reachability, explicit cross joins, positional or named selections, collection, ordering, pages, counts, existence checks, and direct reductions/grouping.

Next steps