class_docstr: caliban job
  
  This class constitutes an execution of a job on a compute platform.
  
  properties:
  id (int): unique id populated by database backend
  created (datetime): creation timestamp
  spec (JobSpec): spec for this job
  experiment (Experiment): experiment associated with this job
  container (str): container id
  status (JobStatus): execution status
  details (JSON): job- and platform-specific details for job
  user (str): username
class_docstr_tok: ["caliban","job","This","class","constitutes","an","execution","of","a","job","on","a","compute","platform",".","properties",":","id","(","int",")",":","unique","id","populated","by","database","backend","created","(","datetime",")",":","creation","timestamp","spec","(","JobSpec",")",":","spec","for","this","job","experiment","(","Experiment",")",":","experiment","associated","with","this","job","container","(","str",")",":","container","id","status","(","JobStatus",")",":","execution","status","details","(","JSON",")",":","job-","and","platform-specific","details","for","job","user","(","str",")",":","username"]
docstr: Job
  
  spec: job spec
  container: container id for this job
  details: job- and platform-specific details for job
  status: initial status for this job
  user: user who created this job, if None will be auto-detected
docstr_tok: ["Job","spec",":","job","spec","container",":","container","id","for","this","job","details",":","job-","and","platform-specific","details","for","job","status",":","initial","status","for","this","job","user",":","user","who","created","this","job",",","if","None","will","be","auto-detected"]
code: def __init__(
      self,
      spec: JobSpec,
      container: str,
      details: Dict[str, Any],
      status: Optional[JobStatus] = JobStatus.SUBMITTED,
      user: Optional[str] = None,
  ):
      """Job
  
      spec: job spec
      container: container id for this job
      details: job- and platform-specific details for job
      status: initial status for this job
      user: user who created this job, if None will be auto-detected
      """
      self.created = datetime.now().astimezone()
      self.container = container
      self.details = sorted_dict(
          details
      )  # 'metadata' is reserved by sqlalchemy
      self.status = status
      self.user = user or current_user()
  
      spec.jobs.append(self)
      spec.experiment.jobs.append(self)
  
imports: import json
  from collections import OrderedDict
  from datetime import datetime
  from enum import Enum
  from typing import Any, Dict, List, Optional
  import sqlalchemy
  from sqlalchemy import JSON, Column, DateTime, ForeignKey, Integer, String
  from sqlalchemy.engine.base import Engine
  from sqlalchemy.ext.declarative import declarative_base
  from sqlalchemy.orm import Session, backref, relationship, sessionmaker
  from sqlalchemy.orm.session import object_session
  from caliban.util import current_user
label_desc: Use image node_id 1 to create a new Job object from inherited base classes: Base with example: obj = Job(spec, container, details, status, user)