Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 54 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
# novem - data visualisation for coders

A wrapper library for the novem.io data visualisation platform. Create charts,
documents, e-mails and dashboards through one simple API.
documents, e-mails, and dashboards through one simple API.

**NB:** novem is currently in closed alpha, if you want to try it out please
**Note:** novem is currently in closed alpha. If you want to try it out, please
reach out to hello@novem.io


## Examples

Create a linechart from a pandas dataframe (assumes a configured profile
see "Getting started" below).
Create a linechart from a pandas dataframe (this assumes a configured profile,
described under "Getting started" below).

```python
import numpy as np
Expand Down Expand Up @@ -59,7 +59,7 @@ These are resolved, in order of precedence, from:
4. the config file written by `python -m novem --init`

The simplest setup is the config file (`--init` above). To configure novem
programmatically instead handy in notebooks, scripts or CI set a token on
programmatically instead (handy in notebooks, scripts, or CI), set a token on
the global `novem.config` object once, and objects created afterwards pick it
up automatically:

Expand All @@ -82,9 +82,9 @@ plot = novem.Plot("my-plot", token="your-token")
```

### Multiple accounts / profiles
A `Session` captures connection settings (token, api_root or a config-file
profile) and constructs objects bound to them, without touching the global
defaults — useful when working against several accounts at once:
A `Session` captures connection settings (token, api_root, or a config-file
profile) and constructs objects bound to them without touching the global
defaults — useful when you work against several accounts at once:

```python
import novem
Expand All @@ -105,7 +105,7 @@ novem package `from novem import Plot`.
The `Plot` class takes a single mandatory positional argument, the name of the
plot.
* If the plot name is new, the instantiation of the class will create the plot.
* If the plot name already exist, then the new object will operate on the
* If the plot name already exists, then the new object will operate on the
existing plot.

In addition to the name, there are two broad categories of options for a
Expand All @@ -117,7 +117,7 @@ plot: data and config.
* Titles/captions/names/colors/legends/axis etc


There are two ways to interact with the plots, one can either supply all
There are two ways to interact with the plots: you can either supply all
the necessary options as named arguments when creating the plot, or use the
property accessors to modify them one by one (this is more helpful when working
with the plot interactively). Below is an example of both approaches.
Expand Down Expand Up @@ -171,13 +171,56 @@ df.pipe(line)
```


**NB:** All novem plot operations are live.
**Note:** All novem plot operations are live.
This means that as soon as you write to or modify any aspects of the plot
object, those changes are reflected on the novem server and anyone watching
the plot in real time.



## Error handling
Every novem operation talks to the platform over the network, so any call can
fail: a rejected token, a missing resource, or a value the server won't accept.
When a read or write fails, novem raises a `NovemException` (or a more specific
subclass) carrying the server's error message instead of failing silently.

```python
from novem import Plot
from novem.exceptions import NovemException, Novem403

try:
# the constructor creates the plot (a PUT) unless create=False, so this
# call can raise too, not only the writes that follow it
plot = Plot("my-plot")
plot.type = "line"
except Novem403:
print("not permitted to write this plot")
except NovemException as e:
# the exception carries the server message and any rejected lines
print(f"novem rejected the write: {e}")
```

Every exception is importable from `novem.exceptions` and inherits from
`NovemException`, so catching the base class catches them all:

* `NovemException`: the base class, raised for any otherwise-unclassified API
error.
* `Novem401`: the server rejected the supplied token.
* `Novem403`: the token is valid but lacks permission for this operation.
* `Novem404`: the resource does not exist.
* `NovemAuthError`: no usable token could be resolved locally. This is distinct
from `Novem401`, which is the server rejecting a token that was sent.

Note: creating an object that already exists is not an error — the create PUT
returns a 409, which novem treats as a no-op rather than raising.

### Timeouts
novem requests time out instead of hanging indefinitely. Every call uses a
default timeout of `(10s connect, 2min read)`. Job execution (`job.run()`) can
take far longer and uses `(30s connect, 30min read)`. A request that exceeds its
timeout raises `requests.exceptions.Timeout`.


## Contribution and development
The novem python library and platform is under active development, contributions
or issues are most welcome.
Expand Down