File: README.md

package info (click to toggle)
python-scooby 0.11.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 360 kB
  • sloc: python: 1,115; makefile: 32
file content (462 lines) | stat: -rw-r--r-- 14,687 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
# 🐶🕵️ Scooby

[![Downloads](https://img.shields.io/pypi/dm/scooby.svg?label=PyPI%20downloads)](https://pypi.org/project/scooby/)
[![Tests](https://github.com/banesullivan/scooby/actions/workflows/pythonpackage.yml/badge.svg)](https://github.com/banesullivan/scooby/actions/workflows/pythonpackage.yml)
[![PyPI Status](https://img.shields.io/pypi/v/scooby.svg?logo=python&logoColor=white)](https://pypi.org/project/scooby/)
[![Conda Status](https://img.shields.io/conda/vn/conda-forge/scooby.svg)](https://anaconda.org/conda-forge/scooby)
[![codecov](https://codecov.io/gh/banesullivan/scooby/branch/main/graph/badge.svg?token=eJqZ700tqH)](https://codecov.io/gh/banesullivan/scooby)

*Great Dane turned Python environment detective*

This is a lightweight tool for easily reporting your Python environment's
package versions and hardware resources.


Install from [PyPI](https://pypi.org/project/scooby/)

```bash
pip install scooby
```

or from [conda-forge](https://anaconda.org/conda-forge/scooby/)

```bash
conda install -c conda-forge scooby
```

![Jupyter Notebook Formatting](https://github.com/banesullivan/scooby/raw/main/assets/jupyter.png)

Scooby has HTML formatting for Jupyter notebooks and rich text formatting for
just about every other environment. We designed this module to be lightweight
such that it could easily be added as a dependency to Python projects for
environment reporting when debugging. Simply add scooby to your dependencies
and implement a function to have scooby report on the aspects of the
environment you care most about.

If scooby is unable to detect aspects of an environment that you'd like to
know, please share this with us as a feature requests or pull requests.

The scooby reporting is derived from the versioning-scripts created by [Dieter
Werthmüller](https://github.com/prisae) for
[empymod](https://empymod.github.io), [emg3d](https://empymod.github.io), and
the [SimPEG](https://github.com/simpeg/) framework. It was heavily inspired by
`ipynbtools.py` from [qutip](https://github.com/qutip) and
[`watermark.py`](https://github.com/rasbt/watermark). This package has been
altered to create a lightweight implementation so that it can easily be used as
an environment reporting tool in any Python library with minimal impact.

## Usage

### Generating Reports

Reports are rendered as html-tables in Jupyter notebooks as shown in the
screenshot above, and otherwise as plain text lists. If you do not output the
`Report` object either at the end of a notebook cell or it is generated
somewhere in a vanilla Python script, you may have to print the `Report`
object: `print(scooby.Report())`, but note that this will only output the plain
text representation of the script.

```py
>>> import scooby
>>> scooby.Report()
```
```
--------------------------------------------------------------------------------
  Date: Wed Feb 12 15:35:43 2020 W. Europe Standard Time

                OS : Windows
            CPU(s) : 16
           Machine : AMD64
      Architecture : 64bit
               RAM : 31.9 GiB
       Environment : IPython

  Python 3.7.6 | packaged by conda-forge | (default, Jan  7 2020, 21:48:41)
  [MSC v.1916 64 bit (AMD64)]

             numpy : 1.18.1
             scipy : 1.3.1
           IPython : 7.12.0
        matplotlib : 3.0.3
            scooby : 0.5.0

  Intel(R) Math Kernel Library Version 2019.0.4 Product Build 20190411 for
  Intel(R) 64 architecture applications
--------------------------------------------------------------------------------
```

For all the Scooby-Doo fans out there, `doo` is an alias for `Report` so you
can oh-so satisfyingly do:

```py
>>> import scooby
>>> scooby.doo()
```
```
--------------------------------------------------------------------------------
  Date: Thu Nov 25 09:47:50 2021 MST

                OS : Darwin
            CPU(s) : 12
           Machine : x86_64
      Architecture : 64bit
               RAM : 32.0 GiB
       Environment : Python
       File system : apfs

  Python 3.8.12 | packaged by conda-forge | (default, Oct 12 2021, 21:50:38)
  [Clang 11.1.0 ]

             numpy : 1.21.4
             scipy : 1.7.3
           IPython : 7.29.0
        matplotlib : 3.5.0
            scooby : 0.5.8
--------------------------------------------------------------------------------
```

Or better yet:

```py
from scooby import doo as doobiedoo
```

On top of the default (optional) packages you can provide additional packages,
either as strings or give already imported packages:
```py
>>> import pyvista
>>> import scooby
>>> scooby.Report(additional=[pyvista, 'vtk', 'no_version', 'does_not_exist'])
```
```
--------------------------------------------------------------------------------
  Date: Wed Feb 12 16:15:15 2020 W. Europe Standard Time

                OS : Windows
            CPU(s) : 16
           Machine : AMD64
      Architecture : 64bit
               RAM : 31.9 GiB
       Environment : IPython

  Python 3.7.6 | packaged by conda-forge | (default, Jan  7 2020, 21:48:41)
  [MSC v.1916 64 bit (AMD64)]

           pyvista : 0.23.1
               vtk : 8.1.2
        no_version : Version unknown
    does_not_exist : Could not import
             numpy : 1.18.1
             scipy : 1.3.1
           IPython : 7.12.0
        matplotlib : 3.0.3
            scooby : 0.5.0

  Intel(R) Math Kernel Library Version 2019.0.4 Product Build 20190411 for
  Intel(R) 64 architecture applications
--------------------------------------------------------------------------------
```

Furthermore, scooby reports if a package could not be imported or if the
version of a package could not be determined.

Other useful parameters are

- `ncol`: number of columns in the html-table;
- `text_width`: text width of the plain-text version;
- `sort`: list is sorted alphabetically if True.

Besides `additional` there are two more lists, `core` and `optional`, which
can be used to provide package names. However, they are mostly useful for
package maintainers wanting to use scooby to create their reporting system
(see below).


### Implementing scooby in your project

You can easily generate a custom `Report` instance using scooby within your
project:

```py
class Report(scooby.Report):
    def __init__(self, additional=None, ncol=3, text_width=80, sort=False):
        """Initiate a scooby.Report instance."""

        # Mandatory packages.
        core = ['yourpackage', 'your_core_packages', 'e.g.', 'numpy', 'scooby']

        # Optional packages.
        optional = ['your_optional_packages', 'e.g.', 'matplotlib']

        scooby.Report.__init__(self, additional=additional, core=core,
                               optional=optional, ncol=ncol,
                               text_width=text_width, sort=sort)
```

This makes it particularly easy for a user of your project to quickly generate
a report on all of the relevant package versions and environment details when
submitting a bug.

```py
>>> import your_package
>>> your_package.Report()
```

The packages on the `core`-list are the mandatory ones for your project, while
the `optional`-list can be used for optional packages. Keep the
`additional`-list free to allow your users to add packages to the list.

#### Implementing as a soft dependency

If you would like to implement scooby, but are hesitant to add another
dependency to your package, here is an easy way how you can use scooby as a
soft dependency. Instead of `import scooby` use the following snippet:

```py
# Make scooby a soft dependency:
try:
    from scooby import Report as ScoobyReport
except ImportError:
    class ScoobyReport:
        def __init__(self, *args, **kwargs):
            message = (
                '\n  *ERROR*: `Report` requires `scooby`.'
                '\n           Install it via `pip install scooby` or'
                '\n           `conda install -c conda-forge scooby`.\n'
            )
            raise ImportError(message)
```

and then create your own `Report` class same as above,

```py
class Report(ScoobyReport):
    def __init__(self, additional=None, ncol=3, text_width=80, sort=False):
        """Initiate a scooby.Report instance."""

        # Mandatory packages.
        core = ['yourpackage', 'your_core_packages', 'e.g.', 'numpy', 'scooby']

        # Optional packages.
        optional = ['your_optional_packages', 'e.g.', 'matplotlib']

        scooby.Report.__init__(self, additional=additional, core=core,
                               optional=optional, ncol=ncol,
                               text_width=text_width, sort=sort)

```
If a user has scooby installed, all works as expected. If scooby is not
installed, it will raise the following exception:

```py
>>> import your_package
>>> your_package.Report()

  *ERROR*: `Report` requires `scooby`
           Install it via `pip install scooby` or
           `conda install -c conda-forge scooby`.
```

### Autogenerate Reports for any Packages

Scooby can automatically generate a Report for any package and its
distribution requirements with the `AutoReport` class:

```py
>>> import scooby
>>> scooby.AutoReport('matplotlib')
```
```
--------------------------------------------------------------------------------
  Date: Fri Oct 20 16:49:34 2023 PDT

                OS : Darwin
            CPU(s) : 8
           Machine : arm64
      Architecture : 64bit
               RAM : 16.0 GiB
       Environment : Python
       File system : apfs

  Python 3.11.3 | packaged by conda-forge | (main, Apr  6 2023, 08:58:31)
  [Clang 14.0.6 ]

        matplotlib : 3.7.1
         contourpy : 1.0.7
            cycler : 0.11.0
         fonttools : 4.39.4
        kiwisolver : 1.4.4
             numpy : 1.24.3
         packaging : 23.1
            pillow : 9.5.0
         pyparsing : 3.0.9
   python-dateutil : 2.8.2
--------------------------------------------------------------------------------
```

### Solving Mysteries

Are you struggling with the mystery of whether or not code is being executed in
IPython, Jupyter, or normal Python? Try using some of scooby's investigative
functions to solve these kinds of mysteries:

```py
import scooby

if scooby.in_ipykernel():
    # Do Jupyter/IPyKernel stuff
elif scooby.in_ipython():
    # Do IPython stuff
else:
    # Do normal, boring Python stuff
```

### How does scooby get version numbers?

A couple of locations are checked, and we are happy to implement more if
needed, just open an issue!

Currently, it looks in the following places:
- `__version__`
- `version`
- lookup `VERSION_ATTRIBUTES` in the scooby knowledge base
- lookup `VERSION_METHODS` in the scooby knowledge base

`VERSION_ATTRIBUTES` is a dictionary of attributes for known python packages
with a non-standard place for the version. You can add other known places via:

```py
scooby.knowledge.VERSION_ATTRIBUTES['a_module'] = 'Awesome_version_location'
```

Similarly, `VERSION_METHODS` is a dictionary for methods to retrieve the
version, and you can similarly add your methods which will get the version
of a package.

### Using scooby to get version information.

If you are only interested in the version of a single package then you can use
scooby as well. A few examples:

```py
>>> import scooby, numpy
>>> scooby.get_version(numpy)
('numpy', '1.16.4')
>>> scooby.get_version('no_version')
('no_version', 'Version unknown')
>>> scooby.get_version('does_not_exist')
('does_not_exist', 'Could not import')
```

Note that modules can be provided as already loaded ones or as strings.


### Tracking Imports in a Session

Scooby has the ability to track all imported modules during a Python session
such that *any* imported, non-standard lib package that is used in the session
is reported by a `TrackedReport`. For instance, start a session by importing
scooby and enabling tracking with the `track_imports()` function.
Then *all* subsequent packages that are imported during the session will be
tracked and scooby can report their versions.
Once you are ready to generate a `Report`, instantiate a `TrackedReport` object.

In the following example, we import a constant from `scipy` which will report
the versions of `scipy` and `numpy` as both packages are loaded in the session
(note that `numpy` is internally loaded by `scipy`).

```py
>>> import scooby
>>> scooby.track_imports()

>>> from scipy.constants import mu_0 # a float value

>>> scooby.TrackedReport()
```
```
--------------------------------------------------------------------------------
  Date: Thu Apr 16 15:33:11 2020 MDT

                OS : Linux
            CPU(s) : 8
           Machine : x86_64
      Architecture : 64bit
               RAM : 62.7 GiB
       Environment : IPython

  Python 3.7.7 (default, Mar 10 2020, 15:16:38)  [GCC 7.5.0]

            scooby : 0.5.2
             numpy : 1.18.1
             scipy : 1.4.1
--------------------------------------------------------------------------------
```

## Command-Line Interface

Scooby comes with a command-line interface. Simply typing

```bash
scooby
```

in a terminal will display the default report. You can also use the CLI to show
the scooby Report of another package if that package has implemented a Report
class as suggested above, using `packagename.Report()`.

As an example, to print the report of pyvista you can run

```bash
scooby -r pyvista
```

which will show the Report implemented in PyVista.

The CLI can also generate a report based on the dependencies of a package's
distribution where that package hasn't implemented a Report class. For example,
we can generate a Report for `matplotlib` and its dependencies:

```bash
$ scooby -r matplotlib
--------------------------------------------------------------------------------
  Date: Fri Oct 20 17:03:45 2023 PDT

                 OS : Darwin
             CPU(s) : 8
            Machine : arm64
       Architecture : 64bit
                RAM : 16.0 GiB
        Environment : Python
        File system : apfs

  Python 3.11.3 | packaged by conda-forge | (main, Apr  6 2023, 08:58:31)
  [Clang 14.0.6 ]

         matplotlib : 3.7.1
          contourpy : 1.0.7
             cycler : 0.11.0
          fonttools : 4.39.4
         kiwisolver : 1.4.4
              numpy : 1.24.3
          packaging : 23.1
             pillow : 9.5.0
          pyparsing : 3.0.9
    python-dateutil : 2.8.2
importlib-resources : 5.12.0
--------------------------------------------------------------------------------
```

Simply type

```bash
scooby --help
```

to see all the possibilities.

## Optional Requirements

The following is a list of optional requirements and their purpose:

- `psutil`: report total RAM in GiB
- `mkl-services`: report Intel(R) Math Kernel Library version