Skip to main content

@main.py

mainpy - PyPI mainpy - Python Versions mainpy - license

mainpy - CI scipy-stubs - typed mypy mainpy - basedpyright mainpy - ruff


Basic Examples

With mainpy, there's no need to write if __name__ == '__main__' the boilerplate anymore:

without mainpy with mainpy
if __name__ == '__main__':
    app()

def app(): ...
from mainpy import main

@main
def app(): ...

For async apps, the improvement becomes even more obvious:

without mainpy with mainpy
import asyncio

async def async_app(): ...

if __name__ == '__main__':
    with asyncio.Runner() as runner:
        runner.run(async_app())
from mainpy import main

@main
async def async_app(): ...

External Libraries

Even though mainpy requires no other dependencies than typing_extensions (on Python < 3.10), it has optional support for uvloop, and plays nicely with popular CLI libraries, e.g. click and typer.

uvloop

If you have uvloop installed, mainpy will automatically call uvloop.install() before running your async main function. This can be disabled by setting use_uvloop=False, e.g.:

@main(use_uvloop=False)
async def app(): ...

Click

With click you can simply add the decorator as usual.

[!IMPORTANT] The @mainpy.main decorator must come before @click.command().

import mainpy
import click

@mainpy.main
@click.command()
def click_command():
    click.echo('Hello from click_command')

The function that is decorated with @mainpy.main is executed immediately. But a @click.group must be defined before the command function. In this case, mainpy.main should be called after all has been setup:

import mainpy
import click

@click.group()
def group(): ...

@group.command()
def command(): ...

mainpy.main(group)

Typer

A typer internally does some initialization after a command has been defined. Instead of using @mainpy.main on the command itself, you should use mainpy.main() manually:

import mainpy
import typer

app = typer.Typer()

@app.command()
def command():
    typer.echo('typer.Typer()')

mainpy.main(command)

Debug mode

Optionally, Python's development mode can be emulated by passing debug=True to mainpy.main. This does three things:

@main(debug=True)
def app(): ...

Installation

The mainpy package is available on pypi for Python $\ge 3.10$:

pip install mainpy

Additionally, you can install the uvloop extra which will install uvloop>=0.15.2 (unless you're on windows):

pip install mainpy[uvloop]

Release files for mainpy 1.5.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 mainpy 1.5.0
File Size Uploaded
mainpy-1.5.0.tar.gz 6.8 kB Details

Built distribution (wheel)

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

Total release size: 12.7 kB

Release files / mainpy-1.5.0.tar.gz

Download URL mainpy-1.5.0.tar.gz
Size 6.8 kB
Tags Source
SHA-256 checksum
How to use checksums
6083d34ad0f3e0fa07e144f03c9dae32b0fa1554b0213053dd19994c0a169fd8
BLAKE2b-256 checksum
How to use checksums
d0d6e194355f8df0caee4124226308cb5bbfe4f502378cc3ec531e5d4c508144
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2025.

Transparency log

Release files / mainpy-1.5.0-py3-none-any.whl

Download URL mainpy-1.5.0-py3-none-any.whl
Size 5.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6575b02777a7e8e7183197bf45192a2b4dcdd01bd2c2811ac8f800c455bbc3ed
BLAKE2b-256 checksum
How to use checksums
56a661defba8bd47df1ff3935a83b4e2543f446e4450d2686b3f0429e92065a7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

1.5.0 This release

2 release files

1.4.0

2 release files

1.3.2

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.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