vibesketch.document

The vibe-sketch document: model, file I/O and JSON schema.

>>> from vibesketch.document import load, save
>>> document = load("scheme.vsk")
>>> document.species[0].charge
0
>>> save(document, "copy.vsk")
class vibesketch.document.Canvas(*, format, data=<factory>)

Bases: _Strict

The drawing as the canvas engine stores it, embedded verbatim.

Parameters:
format: Literal['ket']
data: dict[str, JsonValue]
model_config = {'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class vibesketch.document.Conformer(*, method, symbols, xyz_angstrom)

Bases: _Strict

One 3D structure of a species: element symbols and Cartesian coordinates.

Parameters:
  • method (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[a-z0-9][a-z0-9_.:+-]{0,63}$, ascii_only=None)])

  • symbols (list[str])

  • xyz_angstrom (list[list[float]])

method: _Token
symbols: list[str]
xyz_angstrom: list[list[float]]
electron_count(charge)

Electrons in the neutral atoms, less the charge.

Parameters:

charge (int)

Return type:

int

model_config = {'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class vibesketch.document.Constraint(*, kind, atoms, value=None)

Bases: _Strict

A coordinate an optimisation holds fixed.

Atoms are 0-based indices into the species’ conformer: the drawing’s atoms first, then the hydrogens.

Parameters:
  • kind (Literal['distance', 'angle', 'dihedral', 'position'])

  • atoms (list[Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0)])]])

  • value (float | None)

kind: Literal['distance', 'angle', 'dihedral', 'position']
atoms: list[Annotated[int, Field(ge=0)]]
value: float | None
model_config = {'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class vibesketch.document.Document(*, schema='vibe-sketch/1', revision=0, canvas=<factory>, species=<factory>, reactions=<factory>, jobs=<factory>, style=<factory>, provenance)

Bases: _Strict

A vibe-sketch document, schema version 1.

Parameters:
model_config = {'extra': 'forbid', 'json_schema_extra': {'description': 'A .vsk file: a drawing and what to compute from it.'}, 'populate_by_name': True, 'title': 'vibe-sketch document', 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

schema_id: Literal['vibe-sketch/1']
revision: int
canvas: Canvas
species: list[Species]
reactions: list[Reaction]
jobs: list[Job]
style: Style
provenance: Provenance
species_by_id(identifier)

The species with identifier; raises KeyError when there is none.

Parameters:

identifier (str)

Return type:

Species

job_by_id(identifier)

The job with identifier; raises KeyError when there is none.

Parameters:

identifier (str)

Return type:

Job

to_json_data()

The document as JSON-compatible data, in the field order of the schema.

Unset optional fields are left out; the canvas data is kept exactly as it came, nulls included.

Return type:

dict[str, Any]

exception vibesketch.document.DocumentError(errors)

Bases: ValueError

A document that is not valid JSON or not a valid vibe-sketch document.

errors lists every problem as "location: message", the form the CLI prints and the REST API returns.

Parameters:

errors (list[str])

Return type:

None

class vibesketch.document.Edit(*, revision, at, actor, client=None, summary)

Bases: _Strict

One revision of the document: who changed it, through what, and why.

Parameters:
  • revision (int)

  • at (AwareDatetime)

  • actor (Literal['human', 'agent', 'system'])

  • client (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[a-z0-9][a-z0-9_.:+-]{0,63}$, ascii_only=None)] | None)

  • summary (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=500, pattern=None, ascii_only=None)])

revision: int
at: AwareDatetime
actor: Literal['human', 'agent', 'system']
client: _Token | None
summary: _Text
model_config = {'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class vibesketch.document.Job(*, id, species, program, spec, runs=None)

Bases: _Strict

A calculation to run on one species with one program.

Parameters:
  • id (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[A-Za-z][A-Za-z0-9_-]{0,63}$, ascii_only=None)])

  • species (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[A-Za-z][A-Za-z0-9_-]{0,63}$, ascii_only=None)])

  • program (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[a-z0-9][a-z0-9_.:+-]{0,63}$, ascii_only=None)])

  • spec (JobSpec)

  • runs (list[Run] | None)

id: _Identifier
species: _Identifier
program: _Token
spec: JobSpec
runs: list[Run] | None
model_config = {'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class vibesketch.document.JobSpec(*, task, method=None, basis=None, aux_basis=None, approximation=None, dispersion=None, solvent=None, states=None, constraints=None, resources=None)

Bases: _Strict

A program-neutral description of a calculation.

Writers translate it into one program’s input and refuse, with a reason, whatever they cannot express (AGENTS.md, ground rule 5). The model only checks that the specification is consistent in itself.

Parameters:
  • task (Literal['geometry', 'sp', 'opt', 'freq', 'opt+freq', 'tddft', 'nmr'])

  • method (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[A-Za-z0-9][A-Za-z0-9()+*/,_.-]{0,63}$, ascii_only=None)] | None)

  • basis (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[A-Za-z0-9][A-Za-z0-9()+*/_.-]{0,63}$, ascii_only=None)] | None)

  • aux_basis (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[A-Za-z0-9][A-Za-z0-9()+*/_.-]{0,63}$, ascii_only=None)] | None)

  • approximation (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[A-Za-z0-9][A-Za-z0-9()_-]{0,31}$, ascii_only=None)] | None)

  • dispersion (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[A-Za-z0-9][A-Za-z0-9()_-]{0,31}$, ascii_only=None)] | None)

  • solvent (Solvent | None)

  • states (int | None)

  • constraints (list[Constraint] | None)

  • resources (Resources | None)

task: Task
method: _MethodName | None
basis: _BasisName | None
aux_basis: _BasisName | None
approximation: _Keyword | None
dispersion: _Keyword | None
solvent: Solvent | None
states: int | None
constraints: list[Constraint] | None
resources: Resources | None
static calculation_fields()

The fields that only mean something for a calculation.

Return type:

tuple[str, …]

model_config = {'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class vibesketch.document.Name(*, value, source, confidence)

Bases: _Strict

A name for a species, with where it came from and how sure it is.

Parameters:
  • value (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=500, pattern=None, ascii_only=None)])

  • source (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[a-z0-9][a-z0-9_.:+-]{0,63}$, ascii_only=None)])

  • confidence (Literal['high', 'medium', 'low'])

value: _Text
source: _Token
confidence: Literal['high', 'medium', 'low']
model_config = {'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class vibesketch.document.Provenance(*, app, created=<factory>, edits=<factory>)

Bases: _Strict

Where the document came from.

Parameters:
  • app (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=500, pattern=None, ascii_only=None)])

  • created (AwareDatetime)

  • edits (list[Edit])

app: _Text
created: AwareDatetime
edits: list[Edit]
model_config = {'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class vibesketch.document.Reaction(*, id, reactants, reagents=<factory>, products, arrow='forward', conditions=<factory>, yield_=None)

Bases: _Strict

One step of a scheme: who reacts, under which conditions, to give what.

Parameters:
  • id (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[A-Za-z][A-Za-z0-9_-]{0,63}$, ascii_only=None)])

  • reactants (list[Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[A-Za-z][A-Za-z0-9_-]{0,63}$, ascii_only=None)]])

  • reagents (list[Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[A-Za-z][A-Za-z0-9_-]{0,63}$, ascii_only=None)]])

  • products (list[Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[A-Za-z][A-Za-z0-9_-]{0,63}$, ascii_only=None)]])

  • arrow (Literal['forward', 'equilibrium', 'retrosynthetic', 'resonance'])

  • conditions (list[Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=500, pattern=None, ascii_only=None)]])

  • yield_ (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=500, pattern=None, ascii_only=None)] | None)

id: _Identifier
reactants: list[_Identifier]
reagents: list[_Identifier]
products: list[_Identifier]
arrow: Arrow
conditions: list[_Text]
yield_: _Text | None
species_ids()
Return type:

list[str]

model_config = {'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class vibesketch.document.Resources(*, nprocs=1, maxcore_mb=None)

Bases: _Strict

What a job may use on the machine that runs it.

Parameters:
  • nprocs (int)

  • maxcore_mb (int | None)

nprocs: int
maxcore_mb: int | None
model_config = {'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class vibesketch.document.Run(*, queue='vibe-queue', host='localhost', id, submitted)

Bases: _Strict

One submission of a job to a queue.

Parameters:
  • queue (Literal['vibe-queue'])

  • host (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$, ascii_only=None)])

  • id (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[A-Za-z0-9_-]{1,64}$, ascii_only=None)])

  • submitted (AwareDatetime)

queue: Literal['vibe-queue']
host: Annotated[str, StringConstraints(pattern='^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$')]
id: Annotated[str, StringConstraints(pattern='^[A-Za-z0-9_-]{1,64}$')]
submitted: AwareDatetime
model_config = {'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class vibesketch.document.Solvent(*, model, name)

Bases: _Strict

An implicit solvation model and the solvent it describes.

Parameters:
  • model (Literal['CPCM', 'SMD'])

  • name (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[A-Za-z0-9][A-Za-z0-9 ,()'-]{0,63}$, ascii_only=None)])

model: Literal['CPCM', 'SMD']
name: _SolventName
model_config = {'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class vibesketch.document.Species(*, id, label=None, smiles=None, inchikey=None, charge=0, multiplicity=1, name=None, conformers=<factory>)

Bases: _Strict

A molecule or ion that appears in the drawing.

Parameters:
  • id (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[A-Za-z][A-Za-z0-9_-]{0,63}$, ascii_only=None)])

  • label (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=500, pattern=None, ascii_only=None)] | None)

  • smiles (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^\S+$, ascii_only=None)] | None)

  • inchikey (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[A-Z]{14}-[A-Z]{10}-[A-Z]$, ascii_only=None)] | None)

  • charge (int)

  • multiplicity (int)

  • name (Name | None)

  • conformers (list[Conformer])

id: _Identifier
label: _Text | None
smiles: _Smiles | None
inchikey: _InChIKey | None
charge: int
multiplicity: int
name: Name | None
conformers: list[Conformer]
model_config = {'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class vibesketch.document.Style(*, preset='acs-1996')

Bases: _Strict

How exported figures look.

Parameters:

preset (Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=None, max_length=None, pattern=^[a-z0-9][a-z0-9_.:+-]{0,63}$, ascii_only=None)])

preset: _Token
model_config = {'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

vibesketch.document.document_json_schema()

The JSON schema (draft 2020-12) of a version-1 document.

Return type:

dict[str, Any]

vibesketch.document.dumps(document)

The document as .vsk text.

Parameters:

document (Document)

Return type:

str

vibesketch.document.from_data(data)

Validate already-parsed JSON data as a document.

Parameters:

data (Any)

Return type:

Document

vibesketch.document.load(path)

Read and validate a document: a .qvf archive or a .vsk file.

Parameters:

path (str | PathLike[str])

Return type:

Document

vibesketch.document.loads(text)

Parse and validate a document from JSON text.

Parameters:

text (str)

Return type:

Document

vibesketch.document.new_document(app=None)

An empty document stamped with this application and the current time.

Parameters:

app (str | None)

Return type:

Document

vibesketch.document.save(document, path)

Write document to path atomically; returns the path written.

A .qvf path gets a QVF archive (raising QvfUnavailable without qvf-writer), any other a .vsk. A file that exists keeps its permissions; a new one gets the umask’s.

Parameters:
Return type:

Path

vibesketch.document.with_edit(document, *, actor, client, summary)

document with an edit recorded for its next revision.

A run of alike edits (same actor, client and summary) folds into one entry, so a drawing session does not leave hundreds. The revision itself is the caller’s to advance: the server’s store does it on commit.

Parameters:
Return type:

Document

Modules

clean

Clean up the drawing: standard bond lengths and angles, everything else kept.

coordinates

Species from 3D structures other programs wrote: QVF sections, XYZ frames.

derive

Derive the normalized layer of a document from its canvas.

embed

3D structures for a document's species, cached in the document.

formats

Import and export: SMILES, MOL, SDF, RXN, CDXML, InChI, names, KET and XYZ.

io

Read and write .vsk files.

ket

The KET bridge: between the canvas engine's JSON and RDKit molecules.

model

The vibe-sketch document, schema version 1.

qvf

QVF, the vibyverse's file format, as vibe-sketch's document format.

schema

The JSON schema of the document, generated from the model.