Skip to main content

functionalytics: Effortless Analytics for Your Python Functions

⚠️ This package is under development, and semi-stable. Expect some changes but not major ones, and feel free to submit any suggestions or bugs.

functionalytics helps you understand how your users interact with your application, without extra code or complex analytics tools. Just add a decorator to your functions, and log every call, argument, and key attribute for later analysis.

Why use functionalytics?

  • Know your users: See which options, features, or inputs are most popular in your app.
  • No hassle: Add a single decorator, no need to rewrite your functions or add tracking code everywhere.
  • Stay in control: Choose what gets logged, redact sensitive data, and summarize large inputs.
  • Analyze easily: Logs are structured for easy parsing and analysis.

The name

  • functionalytics: Rhymes with "functionality"
  • Function analytics: Run analytics for your function calls in your apps
  • Functional: Use functional programming to implement this through a simple decorator

The idea

You have an interactive app, and you want to know how many people use which option:

  • In a country dropdown, which are the most popular countries?
  • How many people enable the "color" checkbox when they create a chart?
  • Are people even using the slider we worked so hard to implement?
  • Are there any performance difference between the different options selected?

These are some example questions that this package aims to help answer

Installation

Requires Python 3.9+.

python3 -m pip install functionalytics

Or with uv:

uv pip install functionalytics

The approach: function decorator + logging (automated)

from functionalytics import log_this

@log_this()
def add(a, b):
    return a + b

add(10, 20)
Calling: __main__.add [2025-07-22T11:35:47.437833+00:00  2025-07-22T11:35:47.438144+00:00] Values: {'a': 10, 'b': 20} Attrs: {} Extra: {}
30

Every time the add function gets called, the given arguments are logged so you can later analyze the user behavior.

Async functions

Async functions work exactly the same way — the decorated function stays a coroutine function, is awaited properly, and timings, errors, and log records all behave as expected:

@log_this()
async def fetch_data(url):
    ...

await fetch_data("https://example.com")

This makes functionalytics work naturally with async frameworks like Quart and FastAPI, as well as sync functions offloaded to worker threads from an event loop.

You also get:

  • Start/end time, which helps audit how fast/slow that particular function is, and if certain inputs cause it to slow down.
  • Module name: Where the function is being called from.
  • Values: Get the actual arguments supplied to your functions (whether default or explicit).
  • Attrs: In some cases you don't want to log the actual arguments. They might be uploaded images, CSV files, sensitive/private data, extremely long strings, or anything that would unnecessarily clutter your log files. In such cases, you can only log certain attributes of those inputs. For example image size, CSV file dimensions, or string lengths, respectively.

Function parameters

  • log_level: The level of logging required to trigger a logging event.
  • file_path: The path of the file where you want to write and store the logs.
  • log_format: In case you want to have a different format.
  • param_attrs: A dictionary with keys being parameter names, and values being a transformer function for each. For example, if you have a string user input that you only want to log its length, you can supply something like this: {"user_input": len}.
  • discard_params: Typically, when you have certain inputs that might clutter log files (or might be private), and that you want to log certain attributes, you will also need to discard those inputs from being logged. This is the option for doing so.
  • extra_data: Allows for logging arbitrary additional data. This can be a dictionary where keys are strings (descriptions of the data) and values are the actual data to be logged, or a callable returning such a dictionary, evaluated at call time (useful for dynamic context like session IDs). The callable may also be async (an async def, or a lambda/partial wrapping one): it is awaited inside a running event loop, or resolved with asyncio.run() in sync contexts such as worker threads.
  • error_file_path: Just like file_path this optional file is where errors get logged, together with the full traceback.
  • log_conditions: You don't always want to log a function call. Sometimes a function would be called with default values which the user didn't initiate, or maybe the default is an empty value, and you don't want to pollute the logs with those. For this parameter you supply a dictionary with the condition(s):
log_conditions = {
    "param_a": lambda a: a is not None,
    "param_b": lambda b: b > 10,
    "param_c": lambda c: c in ["blue", "green", "orange"],
}

log_this(log_conditions=log_conditions)

The logging in this case would only occur if param_a is not None AND param_b is greater than 10, AND param_c is one of ["blue", "green", "orange"]. Maybe you're only interested in analyzing param_b inputs that are big enough so you can audit/analyze those, because you know that it's performing well on values less than 10. You also only want to check what happens only for the colors of interest which you can supply as shown above.

Metadata

Release files for functionalytics 0.7.0

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

Source distribution (sdist)

Source distribution for functionalytics 0.7.0
File Size Uploaded
functionalytics-0.7.0.tar.gz 7.5 kB Details

Built distribution (wheel)

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

Total release size: 16.1 kB

Release files / functionalytics-0.7.0.tar.gz

Download URL functionalytics-0.7.0.tar.gz
Size 7.5 kB
Tags Source
SHA-256 checksum
How to use checksums
1a836233dbc88554df31d78b9df56b201a859eed4c490a8c141d40dd30a23242
BLAKE2b-256 checksum
How to use checksums
71af43a349a89e07a73c469150114f02c199e12066bfd87abd8407a15cc29dcc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / functionalytics-0.7.0-py3-none-any.whl

Download URL functionalytics-0.7.0-py3-none-any.whl
Size 8.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5405428528c4db15a50e4ed07965e59f8df1298adcaf059e4789c97a1f2c5203
BLAKE2b-256 checksum
How to use checksums
a347b3a1ff339bef88d70243268faca8b16a96076f3bdf6c88f2343ba7e6ccaa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.7.0 This release

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

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