Skip to main content
build status coverage downloads downloads

Documentation: runtimedocs.readthedocs.org

What?

runtimedocs is a Python library that offers a sensible, customizable, human-friendly way to get a sense of what really happens during a function call. It implements a decorator which wraps your function/class and prints its runtime behavior and also saves it to a log file usually named as follows: module_name.function_name.rundimedocs.log.

Why?

If you ever found yourself in one or more of these situations then runtimedocs could really help:

  • you would like to know which function called your function(the one you decorated using runtimedocs).

  • you would like to know what were the positional and key-word arguments received by your function at runtime.

  • you want to write docstrings for a (legacy)function with unclear parameters naming and would like to know more about them to help you get started. For instance if that function expect a parameter named “x”, you are much more advanced if you know that during runtime “x” is usually of type=list, of value=[‘bar’, ‘foo’], of len=2.

  • likewise, you may want to debug a function but ignore what are its expected input parameters and returned values (ie: their types and values). A good idea could be to decorate that function in your running environment and runtimedocs will log both the successfull and failling calls along with their inputs(types, and values) so you can know which paramters actually break your functiom.

  • you would like to know if a function is multi output(eg: return foo, bla) or single output(eg: return foo). along with the types and values of the returned variables.

  • your function runs well on a given host but breaks on another, runtimedocs tells you the hostname of the computer running your function.

Features

  • what was the expected signature of a function/class.

  • what was the actual signature used when calling that function/class at run time.

  • where was the function/class declared in and called from.

  • what’s the hostname of the machine running the code.

  • what are the types, names, values of the input parameters and returned values of that function.

  • when relevant also add specific information like their : len, signature, inheritance_tree, etc …

  • what were the positional/key-word arguments at call time.

  • has the function exited successfully or ran into an exception.

  • how long it took to run in case of success.

  • display what was the exception otherwise and raises it back to not side-effect your program.

All these information are saved in a file usually named as follows: module_name.function_name.rundimedocs.log Additionally they can be printed on the terminal if the verbosity level is set to 1. You can easily toggle the runtimedocs decorator off by setting the env variable DISABLE_RUNTIMEDOCS to True.

Quickstart

$ pip install runtimedocs
>>> from runtimedocs import runtimedocs

>>> #decorate the function/class of your choice
>>> @runtimedocs(verbosity=1, timing_info=False) #verbosity=1 means also print the logs on terminal. timing_info=False means don't log time.
... def myadd(a, b, f=sum):
...     return f([a, b])
...
>>> @runtimedocs(verbosity=1, timing_info=False)
... def mysum(elements):
...     return sum(elements)
...
>>> #call the decorated function and see the runtime documentation printed on the terminal and saved to a file called: __main__.myadd.runtimedocs.log
>>> myadd(1, 2)
####################################################################################################
#calling [myadd] declared inside module [__main__]
#caller name: [runtimedocs.core]
#ran inside: hostname=[Juniors-MBP.lan]
#----------------------------------------------------------------------------------------------------
#declared signature = myadd(a, b, f=<built-in function sum>, not_used=None)
#called   signature = myadd(<class 'int'>, <class 'int'>, f=<class 'builtin_function_or_method'>)
#----------------------------------------------------------------------------------------------------
#Number of positional paramters: 2
#    #0:
#     type = <class 'int'>
#     value = 1
#-----
#    #1:
#     type = <class 'int'>
#     value = 2
#-----
#Number of key word paramters: 1
#    f:
#     type = <class 'builtin_function_or_method'>
#     name = sum
#     signature = (iterable, start=0, /)
#     fullargspec = FullArgSpec(args=['iterable', 'start'], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={})
#     isbuiltin = True
#-----
#----------------------------------------------------------------------------------------------------
#[myadd] ran successfully in [0.0]seconds and its returned value has these specs:
#single output return statement:
#     type = <class 'int'>
#     value = 3
#-----

>>> mysum([1, 2]) #logs printed and saved to a file called: __main__.mysum.runtimedocs.log
#####################################################################################################
#calling [mysum] declared inside module [__main__]
#caller name: [runtimedocs.core]
#ran inside: hostname=[Juniors-MBP.lan]
#----------------------------------------------------------------------------------------------------
#declared signature = mysum(elements)
#called   signature = mysum(<class 'list'>)
#----------------------------------------------------------------------------------------------------
#Number of positional paramters: 1
#    #0:
#     type = <class 'list'>
#     len = 2
#     value = [1, 2]
#-----
#Number of key word paramters: 0
#----------------------------------------------------------------------------------------------------
#[mysum] ran successfully in [0.0]seconds and its returned value has these specs:
#single output return statement:
#     type = <class 'int'>
#     value = 3
#-----

>>> mysum(el for el in [1,2])
######################################################################################################
#calling [mysum] declared inside module [__main__]
#caller name: [runtimedocs.core]
#ran inside: hostname=[Juniors-MBP.lan]
#----------------------------------------------------------------------------------------------------
#declared signature = mysum(elements)
#called   signature = mysum(<class 'generator'>)
#----------------------------------------------------------------------------------------------------
#Number of positional paramters: 1
#    #0:
#     type = <class 'generator'>
#     value = <generator object <genexpr> at 0x107b664f8>
#-----
#Number of key word paramters: 0
#----------------------------------------------------------------------------------------------------
#[mysum] ran successfully in [0.0]seconds and its returned value has these specs:
#single output return statement:
#     type = <class 'int'>
#     value = 3
#-----

User’s Guide

Disabling runtimedocs

Disable runtimedocs globally:

>>> import os
>>> #set the DISABLE_RUNTIMEDOCS to '1' which will casted to True (like any other non-empty string).
>>> os.environ['DISABLE_RUNTIMEDOCS'] = '1'
>>> #with DISABLE_RUNTIMEDOCS env variable set to True, runtimedocs decorator doesn't wrap your function, so calling these functions wont't print or save any log file.
>>> myadd(1, 2)
>>> mysum([1, 2])

Disable runtimedocs globally but force enable locally:

>>> import os
>>> #set the DISABLE_RUNTIMEDOCS to '1' which will casted to True (like any other non-empty string).
>>> os.environ['DISABLE_RUNTIMEDOCS'] = '1'
>>> @runtimedocs(verbosity=1, timing_info=False, force_enable_runtimedocs=True)
... def mysum(elements):
...     return sum(elements)
...
>>> myadd(1, 2) #no logs for myadd
>>> mysum([1, 2]) #force_enable_runtimedocs is set to True for mysum so runtimedocs will log the function call.
#####################################################################################################
#calling [mysum] declared inside module [__main__]
#caller name: [runtimedocs.core]
#ran inside: hostname=[Juniors-MBP.lan]
#----------------------------------------------------------------------------------------------------
#declared signature = mysum(elements)
#called   signature = mysum(<class 'list'>)
#----------------------------------------------------------------------------------------------------
#Number of positional paramters: 1
#    #0:
#     type = <class 'list'>
#     len = 2
#     value = [1, 2]
#-----
#Number of key word paramters: 0
#----------------------------------------------------------------------------------------------------
#[mysum] ran successfully in [0.0]seconds and its returned value has these specs:
#single output return statement:
#     type = <class 'int'>
#     value = 3
#-----

Customizations

Customized how runtimedocs parse a given type:

>>> from collections import OrderedDict
>>> # define the function to parse a type as you like, preferably return an orderdict to see them printed in the order you want.
>>> def my_custom_list_parser_func(L):
...    return OrderedDict(
...        bar = 'bar',
...        foo = 'foo',
...        mylist_type = type(L),
...        mylist_len = len(L),
...        mylist_repr =repr(L))
...
>>> custom_parsers_dict = {"<class 'list'>": my_custom_list_parser_func}
>>> @runtimedocs(verbosity=1, timing_info=False, custom_types_parsers_dict=custom_parsers_dict)
... def mysum(elements):
...     return sum(elements)
...
>>> mysum([1,2])
#####################################################################################################
#calling [mysum] declared inside module [__main__]
#caller name: [runtimedocs.core]
#ran inside: hostname=[Juniors-MBP.lan]
#----------------------------------------------------------------------------------------------------
#declared signature = mysum(elements)
#called   signature = mysum(<class 'list'>)
#----------------------------------------------------------------------------------------------------
#Number of positional paramters: 1
#    #0:
#     bar = bar
#     foo = foo
#     mylist_type = <class 'list'>
#     mylist_len = 2
#     mylist_repr = [1, 2]
#-----
#Number of key word paramters: 0
#----------------------------------------------------------------------------------------------------
#[mysum] ran successfully in [0.0]seconds and its returned value has these specs:
#single output return statement:
#     type = <class 'int'>
#     value = 3
#-----

Aggregate all the logs for multiple functions in a same file:

>>> import logging
>>> file_handler = logging.FileHandler('aggregation.runtimedocs.log')

>>> @runtimedocs(extra_logger_handlers=[file_handler])
>>> def myadd(a, b, f=sum, not_used=None):
...     return f([a, b])
...
>>> #even faster, you can also directly pass the string as an extra_hanlder
>>> @runtimedocs(extra_logger_handlers=[file_handler])
>>> def mysum(elements):
...     return sum(elements)
...
>>> # after running these two functions 3 log files will be created: 2 for each function as usual and a 3rd one for the agregated logs
>>> mysum([1,2])
>>> myadd(1, 2, f=sum)
>>> # content of aggregation.runtimedocs.log :
#####################################################################################################
#calling [myadd] declared inside module [__main__]
#caller name: [runtimedocs.core]
#ran inside: hostname=[Juniors-MBP.lan]
#----------------------------------------------------------------------------------------------------
#declared signature = myadd(a, b, f=<built-in function sum>, not_used=None)
#called   signature = myadd(<class 'int'>, <class 'int'>, f=<class 'builtin_function_or_method'>)
#----------------------------------------------------------------------------------------------------
#Number of positional paramters: 2
#    #0:
#     type = <class 'int'>
#     value = 1
#-----
#    #1:
#     type = <class 'int'>
#     value = 2
#-----
#Number of key word paramters: 1
#    f:
#     type = <class 'builtin_function_or_method'>
#     name = sum
#     signature = (iterable, start=0, /)
#     fullargspec = FullArgSpec(args=['iterable', 'start'], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={})
#     isbuiltin = True
#-----
#----------------------------------------------------------------------------------------------------
#[myadd] ran successfully in [0.0]seconds and its returned value has these specs:
#single output return statement:
#     type = <class 'int'>
#     value = 3
#-----
#####################################################################################################
#calling [mysum] declared inside module [__main__]
#caller name: [runtimedocs.core]
#ran inside: hostname=[Juniors-MBP.lan]
#----------------------------------------------------------------------------------------------------
#declared signature = mysum(elements)
#called   signature = mysum(<class 'list'>)
#----------------------------------------------------------------------------------------------------
#Number of positional paramters: 1
#    #0:
#     type = <class 'list'>
#     len = 2
#     value = [1, 2]
#-----
#Number of key word paramters: 0
#----------------------------------------------------------------------------------------------------
#[mysum] ran successfully in [0.0]seconds and its returned value has these specs:
#single output return statement:
#     type = <class 'int'>
#     value = 3
#-----

Documentation/Api

Further documentation can be found at runtimedocs.readthedocs.org

Bugs/Requests

Please use the GitHub issue tracker to submit bugs or request features.

Todos

Add changes to handle Python2.

Contributing

Contributions are welcome, especially with custom type parsers. See runtimedocs_types_parsers for what’s currently supported.

License

Copyright Junior Teudjio Mbativou, 2018.

Distributed under the terms of the MIT license, runtimedocs is a free and open source software.

Metadata

Release files for runtimedocs 1.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for runtimedocs 1.0.2
File Size Uploaded Provenance Actions
runtimedocs-1.0.2.tar.gz 13.0 kB Without provenance Details for runtimedocs-1.0.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for runtimedocs 1.0.2
File Interpreter ABI Platform Actions
runtimedocs-1.0.2-py3-none-any.whl Python 3 none any Details for runtimedocs-1.0.2-py3-none-any.whl

Total release size: 23.2 kB

Release files / runtimedocs-1.0.2.tar.gz

Download URL runtimedocs-1.0.2.tar.gz
Size 13.0 kB
Tags Source
SHA-256 checksum
How to use checksums
ce9a3817404d252a0593e143094912d2489fb0e12cd48a660b6d69812a41815d
BLAKE2b-256 checksum
How to use checksums
96af60f32743280680ca1318bcffddea672e84fb119a98d781aea59f9917b2c1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/1.11.0 pkginfo/1.4.2 requests/2.19.1 setuptools/40.2.0 requests-toolbelt/0.8.0 tqdm/4.25.0 CPython/3.7.0

Release files / runtimedocs-1.0.2-py3-none-any.whl

Download URL runtimedocs-1.0.2-py3-none-any.whl
Size 10.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
45dec8c69f00a7c6582ff6b57ca59c94bd1552d3465a06a75fc62507d1603a85
BLAKE2b-256 checksum
How to use checksums
a847d14859c3a52c913aef652fc4ba3035fe1fe8d6e912662ac6071cc71dad36
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/1.11.0 pkginfo/1.4.2 requests/2.19.1 setuptools/40.2.0 requests-toolbelt/0.8.0 tqdm/4.25.0 CPython/3.7.0

Security for runtimedocs 1.0.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.2 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page