class_docstr: Callback that streams epoch results to a [Weights & Biases](https://self.wandb.ai/) run.
  
  ```python
  self.wandb.login()
  wandb_logger = WandbCallback(project="sample-self.wandb-project", job_type="train")
  model.fit(X_train, Y_train, callbacks=[wandb_logger])
  ```
class_docstr_tok: ["Callback","that","streams","epoch","results","to","a","[","Weights","&","Biases","]","(","https",":","\/\/self.wandb.ai\/",")","run",".","``","`","python","self.wandb.login","(",")","wandb_logger","=","WandbCallback","(","project=","''","sample-self.wandb-project","''",",","job_type=","''","train","''",")","model.fit","(","X_train",",","Y_train",",","callbacks=","[","wandb_logger","]",")","``","`"]
code: def on_epoch_end(self, epoch: int, logs=None):
      logs = logs or {}
      for key in self._constant_fields:
          self._constants[key] = logs[key]
          logs.pop(key, None)
          logs.pop("val_" + key, None)
  
      if self.keys is None:
          self.keys = logs.keys()
  
      if self.write_per_batch:
          for key in logs:
              log_key = key
              if log_key[:4] != "val_":
                  log_key = "train_" + log_key
              self.run.log({log_key: logs[key]}, step=self.global_step)
  
      elif epoch % self.update_freq == 0:
          for key in logs:
              log_key = key
              if log_key[:4] != "val_":
                  log_key = "train_" + log_key
              self.run.log({log_key: logs[key]}, step=epoch)
  
      if self._save_model:
          if self._mode == "every":
              self._best_epoch = epoch
              self._model_path = f"model-{epoch + 1}-{self.run.name}"
              print(f"Saving Model at {self._model_path}")
              self._model_checkpoint = self.model
              self._model_checkpoint.save(self._model_path)
  
          elif (
              self._mode == "min"
              and logs[self._monitor] < self._monitor_metric_val
          ):
              self._best_epoch = epoch
              self._model_path = (
                  f"model-best-{epoch + 1}-{self.run.name}"
              )
              print(
                  f"{self._monitor} decreased at epoch {epoch}. Saving Model at {self._model_path}"
              )
              self._model_checkpoint = self.model
              self._model_checkpoint.save(self._model_path)
              self._monitor_metric_val = logs[self._monitor]
  
          elif (
              self._mode == "max"
              and logs[self._monitor] > self._monitor_metric_val
          ):
              self._best_epoch = epoch
              self._model_path = (
                  f"model-best-{epoch + 1}-{self.run.name}"
              )
              print(
                  f"{self._monitor} increased at epoch {epoch}. Saving Model at {self._model_path}"
              )
              self._model_checkpoint = self.model
              self._model_checkpoint.save(self._model_path)
              self._monitor_metric_val = logs[self._monitor]
  
          self._add_model_as_artifact(
              self._model_path, epoch=self._best_epoch
          )
  
file_path: elegy/elegy/callbacks/wandb_callback.py
imports: import math
  from typing import Dict, Optional, Union
  from .callback import Callback
label_desc: Use image node_id 7 for calling the WandbCallback obj's underlying member method code with example usage: obj.on_epoch_end(epoch, logs) without return types