A Run in Neptune is a representation of all metadata that you log to Neptune, beginning when you start a tracked run with neptune.init() and ending when the script finishes or when you explicitly stop the experiment with .stop() .

import as neptune
# Create new experiment
run = neptune.init('my_workspace/my_project')
# Log parameters
params = {'max_epochs': 10, 'optimizer': 'Adam'}
run['parameters'] = params
# Log metadata
# Log whatever else you want
# Stop tracking and clean up

You can log many ML metadata types, including:

  • metrics,

  • losses,

  • model weights,

  • images,

  • interactive charts,

  • predictions,

  • and much more.

Have a look at the complete list of metadata types you can log.

Besides logging data, you can also download run's data to your local machine.

You can also resume the runs you have created in the past and update them or continue logging metadata to them.

[] (field lookup)

You can access any run's field through a dict-like field lookup run[field_path].

This way you can both track metadata:

run['params/max_epochs'] = 20
for epoch in range(20):

As well as fetch already tracked metadata - fetching parameters when resuming a run or downloading metadata for a custom analysis:

learning_rate = run['params/lr'].fetch()
acc_df = run['train/epoch/acc'].fetch_values()


The returned type depends on the field's type and whether a field is stored under the given path



The field exists.

The returned type matches type of the field.

The field does not exist

Handler object

The path is a namespace e.g. train when a field train/acc exists.

Namespace handler object


import as neptune
run = neptune.init('my_workspace/my_project')
# Create new Float field
run['parameters/momentum'] = 0.9
# Update value of the field
run['parameters/momentum'] = 0.8
# Error - it's impossible to store a File under Float field
run['parameters/momentum'].upload('sample_data.csv') # Error
# Create new Series fields
run['train/logs'].log('Experimenting Day 1:')
# Continue logging to existing Series fields
run['train/logs'].log('I embark on a journey')
# If you access a Namespace handler
# you can interact with it in a similar way
# to the Run object
params_ns = run['parameters']
params_ns['lr'] = 0.3 # Stores 0.3 under path 'parameters/lr'


Convenience alias for .assign().


Assign values to multiple fields from a dictionary. You can use this method to quickly log all run's parameters.



(dict ) - A dictionary with values to assign, where keys become the paths of the fields.

The dictionary can be nested - in such case the path will be a combination of all keys.


(Boolean, optional, default is False) - If True the client will first wait to send all tracked metadata to the server. This makes the call synchronous, see Connection modes guide.


import as neptune
run = neptune.init()
# Assign multiple fields from a dictionary
params = {"max_epochs": 10, "optimizer": "Adam"}
run["parameters"] = params
# You can always log explicitely parameters one by one
run["parameters/max_epochs"] = 10
run["parameters/optimizer"] = "Adam"
# Dictionaries can be nested
params = {"train": {"max_epochs": 10}}
run["parameters"] = params
# This will log 10 under path "parameters/train/max_epochs"

Pretty prints the structure of the run's metadata. Paths are ordered lexicographically and the whole structure is neatly colored.

See also: .get_structure().


Returns a run's metadata structure in form of a dictionary.

This method can be used to traverse the run's metadata structure programmatically when using Neptune in automated workflows.

See also: .print_structure().

The returned object is a shallow copy of an internal run's structure. Any modifications to it may result in tracking malfunction.


dict with the run's metadata structure.


Returns a direct link to run in Neptune. It's the same link that is printed at the moment of initialization of the run.


str with the URL of the run in Neptune


Removes the field or whole namespace stored under the path completely and all data associated with them. See also .pop().


import as neptune
run = neptune.init()
params = {"max_epochs": 10, "optimizer": "Adam"}
run['model/parameters'] = params
# Delete a field with path 'model/parameters/optimizer'
del run['model/parameters/optimizer']
# You can also delete whole namespace
del run['model/parameters']


Removes the field or whole namespace stored under the path completely and all data associated with them. See also .del().



(str ) - Path of the field or namespace to be removed.


(Boolean, optional, default is True) - If True the client will first wait to send all tracked metadata to the server. This makes the call synchronous, see Connection modes guide.


import as neptune
run = neptune.init()
run['parameters/learninggg_rata'] = 0.3
# Delete a field along with it's data
run['parameters/learning_rate'] = 0.3
# Training finished
# 'model_checkpoint' is a File field
# .pop() can be invoked directly on fields and namespaces
# Following line
# is equiavlent to this line
# or this line
# You can also delete in batch whole namespace


Checks if there is any field or namespace under the specified path.



(str) - The path to check for existence of a field or a namespace


import as neptune
# Resume a run with a SAN-34 identifier
run = neptune.init(run="SAN-34")
# If the training is complete remove training checkpoints if they are there
if run.exists("model/checkpoints") and run["train/finished"].fetch() == True:
del run['model/checkpoints']


Stops the tracked run and kills the synchronization thread. .stop() will be automatically called when a script that created the run finishes or on the destruction of Neptune context. When using Neptune with Jupyter notebooks it's a good practice to stop the tracked run manually as it will be stopped automatically only when the Jupyter kernel stops.



(int or float, optional, default is None) - The method will wait for the specified time for all tracking calls to finish, before stopping the tracked run. If None will wait for all tracking calls to finish.


If you are creating tracked runs from the script you don't need to call .stop():

import as neptune
run = neptune.init()
[...] # Your training or monitoring code
# If you are executing Python script .stop()
# is automatically called at the end for every run

If you are performing multiple training jobs from one script one after the other it is a good practice to .stop() the finished tracked runs as every open run keeps an open connection with Neptune, monitors hardware usage, etc. You can also use Context Managers - Neptune will automatically call .stop()on the destruction of Run context:

import as neptune
# If you are running consecutibe training jobs from the same script
# stop the tracked runs manually at the end of single training job
for config in configs:
run = neptune.init()
[...] # Your training or monitoring code
# You can also use with statement and context manager
for config in configs:
with neptune.init() as run:
[...] # Your training or monitoring code
# .stop() is automatically called
# when code execution exits the with statement

If you are using Jupyter notebooks for creating your runs you need to manually invoke .stop() once the training and evaluation is done.


Fetch values of all non-File Atom fields as a dictionary.

The result will preserve the hierarchical structure of the run's metadata but will contain only non-File Atom fields. You can use this method e.g. to quickly retrieve run parameters.


dict containing all non-File Atom fields values.


import as neptune
# Resume run with SUN-123 identifier
run = neptune.init(project="my_workspace/my_project", run="SUN-123")
# Fetch the runs parameters
params = run["model/params"].fetch()


Wait for all the tracking calls to finish.



(Boolean, optional, default is False) - If True the process will only wait for data to be saved locally from memory, but will not wait for them to reach Neptune servers.


Synchronizes local representation of the run with Neptune servers.



(Boolean, optional, default is True) - If True the client will first wait to send all tracked metadata to the server. This makes the call synchronous, see Connection modes guide.


import as neptune
# Connect to a run from Worker #3
worker_id = 3
run = neptune.init(run='DIST-43', monitoring_namespace='monitoring/{}'.format(worker_id))
# Try to access logs that were created in meantime by Worker #2
worker_2_status = run['status/2'].fetch() # Error if this field was created after this script starts
run.sync() # Synchronizes local representation with Neptune servers.
worker_2_status = run['status/2'].fetch() # No error