Skip to content

Commit a526866

Browse files
author
ArcHound
committed
feat: built-in profiling
1 parent 3d9d01f commit a526866

3 files changed

Lines changed: 63 additions & 1 deletion

File tree

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ To use simply run `cookiecutter gh:ArcHound/python_script_cc`.
1111
- post gen hook to create virtual environment
1212
- return to `stdout` or to a file,
1313
- option for logging verbosity level,
14+
- built-in profiling support
1415
- decorator for measuring time elapsed (log with informative severity)
1516
- option for including the `requests` lib and `requests_cache` lib,
1617
- few options for a default service - name, url and bearer token,

‎cookiecutter.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"requests_cache_name": "{{ cookiecutter.project_slug }}_requests_cache",
88
"service_name": "gitlab",
99
"service_url": "https://gitlab.com",
10-
"service_token": "invalid"
10+
"service_token": "invalid",
11+
"profiling": ["Yes", "No"]
1112
}
1213

‎{{ cookiecutter.project_slug }}/{{ cookiecutter.project_slug }}.py‎

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,24 @@ def new_func(ctx, *args, **kwargs):
6969

7070
return update_wrapper(new_func, f)
7171

72+
{%- if cookiecutter.profiling == "Yes" %}
73+
def profile_decorator(f):
74+
@click.pass_context
75+
def new_func(ctx, *args, **kwargs):
76+
if ctx.params["profiling"]:
77+
with cProfile.Profile() as profile:
78+
r = ctx.invoke(f, *args, **kwargs)
79+
with open(ctx.params["profiling_file"], "w") as sfs:
80+
pstats.Stats(profile, stream=sfs).strip_dirs().sort_stats(
81+
ctx.params["profiling_sort_key"]
82+
).print_stats()
83+
return r
84+
else:
85+
r = ctx.invoke(f, *args, **kwargs)
86+
return r
87+
88+
return update_wrapper(new_func, f)
89+
{%- endif %}
7290

7391
@click.command()
7492
{%- if cookiecutter.file_input == "Yes" %}
@@ -123,8 +141,50 @@ def new_func(ctx, *args, **kwargs):
123141
help="Set logging level.",
124142
envvar="LOG_LEVEL"
125143
)
144+
{%- if cookiecutter.profiling == "Yes" %}
145+
@click.option(
146+
"--profiling",
147+
default=False,
148+
is_flag=True,
149+
help="Profile the program - get performance data",
150+
)
151+
@click.option(
152+
"--profiling-file",
153+
help="Profiling output file",
154+
type=click.Path(writable=True, file_okay=True, dir_okay=False),
155+
default=f"/tmp/{{cookiecutter.project_slug}}_profile.log",
156+
show_default=True,
157+
)
158+
@click.option(
159+
"--profiling-sort-key",
160+
help="Profiling sort key",
161+
type=click.Choice(
162+
[
163+
"calls",
164+
"cumulative",
165+
"cumtime",
166+
"file",
167+
"filename",
168+
"module",
169+
"ncalls",
170+
"pcalls",
171+
"line",
172+
"name",
173+
"nfl",
174+
"stdname",
175+
"time",
176+
"tottime",
177+
]
178+
),
179+
default="cumulative",
180+
show_default=True,
181+
)
182+
{%- endif %}
126183
@log_decorator
127184
@time_decorator
185+
{%- if cookiecutter.profiling == "Yes" %}
186+
@profile_decorator
187+
{%- endif %}
128188
def main(
129189
{%- if cookiecutter.file_input == "Yes" %}
130190
input_file,

0 commit comments

Comments
 (0)