Skip to content

Commit 6136528

Browse files
authored
Merge branch 'main' into save-event-creator
2 parents 836c819 + 62a4575 commit 6136528

File tree

68 files changed

+5889
-653
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+5889
-653
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ https://github.com/user-attachments/assets/38f44f4e-be1c-4f84-8db9-63d5ee3e61e5
6565

6666
Join our community for support and discussions. If you have any questions, feel free to reach out to us using one of the following methods:
6767

68+
- [Free live Installation Support](https://calendly.com/codeflash-saurabh/codeflash-setup)
6869
- [Join our Discord](https://www.codeflash.ai/discord)
6970
- [Follow us on Twitter](https://x.com/codeflashAI)
7071
- [Follow us on Linkedin](https://www.linkedin.com/in/saurabh-misra/)
71-
- [Email founders](mailto:[email protected])
7272

7373
## License
7474

codeflash/LICENSE

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Business Source License 1.1
33
Parameters
44

55
Licensor: CodeFlash Inc.
6-
Licensed Work: Codeflash Client version 0.12.x
6+
Licensed Work: Codeflash Client version 0.14.x
77
The Licensed Work is (c) 2024 CodeFlash Inc.
88

99
Additional Use Grant: None. Production use of the Licensed Work is only permitted
@@ -13,7 +13,7 @@ Additional Use Grant: None. Production use of the Licensed Work is only permitte
1313
Platform. Please visit codeflash.ai for further
1414
information.
1515

16-
Change Date: 2029-04-23
16+
Change Date: 2029-06-09
1717

1818
Change License: MIT
1919

codeflash/api/aiservice.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def optimize_python_code( # noqa: D417
123123

124124
if response.status_code == 200:
125125
optimizations_json = response.json()["optimizations"]
126-
logger.info(f"Generated {len(optimizations_json)} candidates.")
126+
logger.info(f"Generated {len(optimizations_json)} candidate optimizations.")
127127
console.rule()
128128
end_time = time.perf_counter()
129129
logger.debug(f"Generating optimizations took {end_time - start_time:.2f} seconds.")
@@ -194,7 +194,7 @@ def optimize_python_code_line_profiler( # noqa: D417
194194

195195
if response.status_code == 200:
196196
optimizations_json = response.json()["optimizations"]
197-
logger.info(f"Generated {len(optimizations_json)} candidates.")
197+
logger.info(f"Generated {len(optimizations_json)} candidate optimizations.")
198198
console.rule()
199199
return [
200200
OptimizedCandidate(

codeflash/api/cfapi.py

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from pathlib import Path
88
from typing import TYPE_CHECKING, Any, Optional
99

10+
import git
1011
import requests
1112
import sentry_sdk
1213
from pydantic.json import pydantic_encoder
@@ -115,7 +116,7 @@ def suggest_changes(
115116
"existingTests": existing_tests,
116117
"generatedTests": generated_tests,
117118
"traceId": trace_id,
118-
"coverage": coverage_message,
119+
"coverage_message": coverage_message,
119120
}
120121
return make_cfapi_request(endpoint="/suggest-pr-changes", method="POST", payload=payload)
121122

@@ -151,7 +152,7 @@ def create_pr(
151152
"existingTests": existing_tests,
152153
"generatedTests": generated_tests,
153154
"traceId": trace_id,
154-
"coverage": coverage_message,
155+
"coverage_message": coverage_message,
155156
}
156157
return make_cfapi_request(endpoint="/create-pr", method="POST", payload=payload)
157158

@@ -179,19 +180,10 @@ def get_blocklisted_functions() -> dict[str, set[str]] | dict[str, Any]:
179180
if pr_number is None:
180181
return {}
181182

182-
not_found = 404
183-
internal_server_error = 500
184-
185183
owner, repo = get_repo_owner_and_name()
186184
information = {"pr_number": pr_number, "repo_owner": owner, "repo_name": repo}
187185
try:
188186
req = make_cfapi_request(endpoint="/verify-existing-optimizations", method="POST", payload=information)
189-
if req.status_code == not_found:
190-
logger.debug(req.json()["message"])
191-
return {}
192-
if req.status_code == internal_server_error:
193-
logger.error(req.json()["message"])
194-
return {}
195187
req.raise_for_status()
196188
content: dict[str, list[str]] = req.json()
197189
except Exception as e:
@@ -200,3 +192,35 @@ def get_blocklisted_functions() -> dict[str, set[str]] | dict[str, Any]:
200192
return {}
201193

202194
return {Path(k).name: {v.replace("()", "") for v in values} for k, values in content.items()}
195+
196+
197+
def is_function_being_optimized_again(
198+
owner: str, repo: str, pr_number: int, code_contexts: list[dict[str, str]]
199+
) -> Any: # noqa: ANN401
200+
"""Check if the function being optimized is being optimized again."""
201+
response = make_cfapi_request(
202+
"/is-already-optimized",
203+
"POST",
204+
{"owner": owner, "repo": repo, "pr_number": pr_number, "code_contexts": code_contexts},
205+
)
206+
response.raise_for_status()
207+
return response.json()
208+
209+
210+
def add_code_context_hash(code_context_hash: str) -> None:
211+
"""Add code context to the DB cache."""
212+
pr_number = get_pr_number()
213+
if pr_number is None:
214+
return
215+
try:
216+
owner, repo = get_repo_owner_and_name()
217+
pr_number = get_pr_number()
218+
except git.exc.InvalidGitRepositoryError:
219+
return
220+
221+
if owner and repo and pr_number is not None:
222+
make_cfapi_request(
223+
"/add-code-hash",
224+
"POST",
225+
{"owner": owner, "repo": repo, "pr_number": pr_number, "code_hash": code_context_hash},
226+
)

codeflash/benchmarking/codeflash_trace.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ def setup(self, trace_path: str) -> None:
2525
"""Set up the database connection for direct writing.
2626
2727
Args:
28+
----
2829
trace_path: Path to the trace database file
2930
3031
"""
@@ -52,6 +53,7 @@ def write_function_timings(self) -> None:
5253
"""Write function call data directly to the database.
5354
5455
Args:
56+
----
5557
data: List of function call data tuples to write
5658
5759
"""
@@ -94,9 +96,11 @@ def __call__(self, func: Callable) -> Callable:
9496
"""Use as a decorator to trace function execution.
9597
9698
Args:
99+
----
97100
func: The function to be decorated
98101
99102
Returns:
103+
-------
100104
The wrapped function
101105
102106
"""

codeflash/benchmarking/instrument_codeflash_trace.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,12 @@ def add_codeflash_decorator_to_code(code: str, functions_to_optimize: list[Funct
7676
"""Add codeflash_trace to a function.
7777
7878
Args:
79+
----
7980
code: The source code as a string
8081
functions_to_optimize: List of FunctionToOptimize instances containing function details
8182
8283
Returns:
84+
-------
8385
The modified source code as a string
8486
8587
"""

codeflash/benchmarking/plugin/plugin.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,11 @@ def get_function_benchmark_timings(trace_path: Path) -> dict[str, dict[Benchmark
7474
"""Process the trace file and extract timing data for all functions.
7575
7676
Args:
77+
----
7778
trace_path: Path to the trace file
7879
7980
Returns:
81+
-------
8082
A nested dictionary where:
8183
- Outer keys are module_name.qualified_name (module.class.function)
8284
- Inner keys are of type BenchmarkKey
@@ -132,9 +134,11 @@ def get_benchmark_timings(trace_path: Path) -> dict[BenchmarkKey, int]:
132134
"""Extract total benchmark timings from trace files.
133135
134136
Args:
137+
----
135138
trace_path: Path to the trace file
136139
137140
Returns:
141+
-------
138142
A dictionary mapping where:
139143
- Keys are of type BenchmarkKey
140144
- Values are total benchmark timing in milliseconds (with overhead subtracted)

codeflash/benchmarking/replay_test.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,14 @@ def create_trace_replay_test_code(
5555
"""Create a replay test for functions based on trace data.
5656
5757
Args:
58+
----
5859
trace_file: Path to the SQLite database file
5960
functions_data: List of dictionaries with function info extracted from DB
6061
test_framework: 'pytest' or 'unittest'
6162
max_run_count: Maximum number of runs to include in the test
6263
6364
Returns:
65+
-------
6466
A string containing the test code
6567
6668
"""
@@ -115,8 +117,7 @@ def create_trace_replay_test_code(
115117
if function_name == "__init__":
116118
ret = {class_name_alias}(*args[1:], **kwargs)
117119
else:
118-
instance = args[0] # self
119-
ret = instance{method_name}(*args[1:], **kwargs)
120+
ret = {class_name_alias}{method_name}(*args, **kwargs)
120121
"""
121122
)
122123

@@ -219,12 +220,14 @@ def generate_replay_test(
219220
"""Generate multiple replay tests from the traced function calls, grouped by benchmark.
220221
221222
Args:
223+
----
222224
trace_file_path: Path to the SQLite database file
223225
output_dir: Directory to write the generated tests (if None, only returns the code)
224226
test_framework: 'pytest' or 'unittest'
225227
max_run_count: Maximum number of runs to include per function
226228
227229
Returns:
230+
-------
228231
Dictionary mapping benchmark names to generated test code
229232
230233
"""

codeflash/benchmarking/utils.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,13 @@ def process_benchmark_data(
8383
"""Process benchmark data and generate detailed benchmark information.
8484
8585
Args:
86+
----
8687
replay_performance_gain: The performance gain from replay
8788
fto_benchmark_timings: Function to optimize benchmark timings
8889
total_benchmark_timings: Total benchmark timings
8990
9091
Returns:
92+
-------
9193
ProcessedBenchmarkInfo containing processed benchmark details
9294
9395
"""

codeflash/cli_cmds/cli.py

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,12 @@
33
from argparse import SUPPRESS, ArgumentParser, Namespace
44
from pathlib import Path
55

6-
import git
7-
86
from codeflash.cli_cmds import logging_config
97
from codeflash.cli_cmds.cli_common import apologize_and_exit
108
from codeflash.cli_cmds.cmd_init import init_codeflash, install_github_actions
119
from codeflash.cli_cmds.console import logger
1210
from codeflash.code_utils import env_utils
1311
from codeflash.code_utils.config_parser import parse_config_file
14-
from codeflash.code_utils.git_utils import (
15-
check_and_push_branch,
16-
check_running_in_git_repo,
17-
confirm_proceeding_with_no_git_repo,
18-
get_repo_owner_and_name,
19-
)
20-
from codeflash.code_utils.github_utils import get_github_secrets_page_url, require_github_app_or_exit
2112
from codeflash.version import __version__ as version
2213

2314

@@ -75,6 +66,13 @@ def parse_args() -> Namespace:
7566

7667

7768
def process_and_validate_cmd_args(args: Namespace) -> Namespace:
69+
from codeflash.code_utils.git_utils import (
70+
check_running_in_git_repo,
71+
confirm_proceeding_with_no_git_repo,
72+
get_repo_owner_and_name,
73+
)
74+
from codeflash.code_utils.github_utils import require_github_app_or_exit
75+
7876
is_init: bool = args.command.startswith("init") if args.command else False
7977
if args.verbose:
8078
logging_config.set_level(logging.DEBUG, echo_setting=not is_init)
@@ -125,6 +123,7 @@ def process_pyproject_config(args: Namespace) -> Namespace:
125123
"disable_telemetry",
126124
"disable_imports_sorting",
127125
"git_remote",
126+
"override_fixtures",
128127
]
129128
for key in supported_keys:
130129
if key in pyproject_config and (
@@ -144,21 +143,26 @@ def process_pyproject_config(args: Namespace) -> Namespace:
144143
assert Path(args.benchmarks_root).resolve().is_relative_to(Path(args.tests_root).resolve()), (
145144
f"--benchmarks-root {args.benchmarks_root} must be a subdirectory of --tests-root {args.tests_root}"
146145
)
147-
if env_utils.get_pr_number() is not None:
148-
assert env_utils.ensure_codeflash_api_key(), (
149-
"Codeflash API key not found. When running in a Github Actions Context, provide the "
150-
"'CODEFLASH_API_KEY' environment variable as a secret.\n"
151-
"You can add a secret by going to your repository's settings page, then clicking 'Secrets' in the left sidebar.\n"
152-
"Then, click 'New repository secret' and add your api key with the variable name CODEFLASH_API_KEY.\n"
153-
f"Here's a direct link: {get_github_secrets_page_url()}\n"
154-
"Exiting..."
155-
)
146+
if env_utils.get_pr_number() is not None:
147+
import git
148+
149+
from codeflash.code_utils.git_utils import get_repo_owner_and_name
150+
from codeflash.code_utils.github_utils import get_github_secrets_page_url, require_github_app_or_exit
151+
152+
assert env_utils.ensure_codeflash_api_key(), (
153+
"Codeflash API key not found. When running in a Github Actions Context, provide the "
154+
"'CODEFLASH_API_KEY' environment variable as a secret.\n"
155+
"You can add a secret by going to your repository's settings page, then clicking 'Secrets' in the left sidebar.\n"
156+
"Then, click 'New repository secret' and add your api key with the variable name CODEFLASH_API_KEY.\n"
157+
f"Here's a direct link: {get_github_secrets_page_url()}\n"
158+
"Exiting..."
159+
)
156160

157-
repo = git.Repo(search_parent_directories=True)
161+
repo = git.Repo(search_parent_directories=True)
158162

159-
owner, repo_name = get_repo_owner_and_name(repo)
163+
owner, repo_name = get_repo_owner_and_name(repo)
160164

161-
require_github_app_or_exit(owner, repo_name)
165+
require_github_app_or_exit(owner, repo_name)
162166

163167
if hasattr(args, "ignore_paths") and args.ignore_paths is not None:
164168
normalized_ignore_paths = []
@@ -187,6 +191,11 @@ def project_root_from_module_root(module_root: Path, pyproject_file_path: Path)
187191

188192
def handle_optimize_all_arg_parsing(args: Namespace) -> Namespace:
189193
if hasattr(args, "all"):
194+
import git
195+
196+
from codeflash.code_utils.git_utils import check_and_push_branch, get_repo_owner_and_name
197+
from codeflash.code_utils.github_utils import require_github_app_or_exit
198+
190199
# Ensure that the user can actually open PRs on the repo.
191200
try:
192201
git_repo = git.Repo(search_parent_directories=True)

0 commit comments

Comments
 (0)