Skip to content

Commit f2733b3

Browse files
committed
Merge branch 'dont-optimize-repeatedly-gh-actions' of https://github.com/codeflash-ai/codeflash into dont-optimize-repeatedly-gh-actions
2 parents 2367160 + 905b1a0 commit f2733b3

File tree

92 files changed

+5829
-1288
lines changed

Some content is hidden

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

92 files changed

+5829
-1288
lines changed

.github/workflows/codeflash-optimize.yaml

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: CodeFlash
22

33
on:
4-
pull_request_target:
4+
pull_request:
55
paths:
66
- '**' # Trigger for all paths
77

@@ -14,8 +14,6 @@ concurrency:
1414
jobs:
1515
optimize:
1616
name: Optimize new Python code
17-
# Dynamically determine if environment is needed only when workflow files change and contributor is external
18-
environment: ${{ (github.event_name == 'workflow_dispatch' || (contains(toJSON(github.event.pull_request.files.*.filename), '.github/workflows/') && github.event.pull_request.user.login != 'misrasaurabh1' && github.event.pull_request.user.login != 'KRRT7')) && 'external-trusted-contributors' || '' }}
1917
if: ${{ github.actor != 'codeflash-ai[bot]' }}
2018
runs-on: ubuntu-latest
2119
env:
@@ -28,31 +26,7 @@ jobs:
2826
- name: 🛎️ Checkout
2927
uses: actions/checkout@v4
3028
with:
31-
ref: ${{ github.event.pull_request.head.ref }}
32-
repository: ${{ github.event.pull_request.head.repo.full_name }}
3329
fetch-depth: 0
34-
- name: Validate PR
35-
run: |
36-
# Check for any workflow changes
37-
if git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}" | grep -q "^.github/workflows/"; then
38-
echo "⚠️ Workflow changes detected."
39-
40-
# Get the PR author
41-
AUTHOR="${{ github.event.pull_request.user.login }}"
42-
echo "PR Author: $AUTHOR"
43-
44-
# Allowlist check
45-
if [[ "$AUTHOR" == "misrasaurabh1" || "$AUTHOR" == "KRRT7" ]]; then
46-
echo "✅ Authorized user ($AUTHOR). Proceeding."
47-
elif [[ "${{ github.event.pull_request.state }}" == "open" ]]; then
48-
echo "✅ PR is open. Proceeding with appropriate protections."
49-
else
50-
echo "⛔ Unauthorized user ($AUTHOR) attempting to modify workflows. Exiting."
51-
exit 1
52-
fi
53-
else
54-
echo "✅ No workflow file changes detected. Proceeding."
55-
fi
5630

5731
- name: 🐍 Set up Python 3.11 for CLI
5832
uses: astral-sh/setup-uv@v5

.github/workflows/end-to-end-test-init-optim.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
COLUMNS: 110
2121
MAX_RETRIES: 3
2222
RETRY_DELAY: 5
23-
EXPECTED_IMPROVEMENT_PCT: 300
23+
EXPECTED_IMPROVEMENT_PCT: 30
2424
CODEFLASH_END_TO_END: 1
2525
steps:
2626
- name: 🛎️ Checkout

.github/workflows/pre-commit.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Lint
2+
on:
3+
pull_request:
4+
push:
5+
branches:
6+
- main
7+
8+
concurrency:
9+
group: ${{ github.workflow }}-${{ github.ref }}
10+
cancel-in-progress: true
11+
12+
jobs:
13+
lint:
14+
name: Run pre-commit hooks
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v4
18+
- uses: actions/setup-python@v5
19+
- uses: pre-commit/[email protected]

.pre-commit-config.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
repos:
2+
- repo: https://github.com/astral-sh/ruff-pre-commit
3+
rev: "v0.11.0"
4+
hooks:
5+
- id: ruff
6+
args: [--fix, --exit-non-zero-on-fix, --config=pyproject.toml]
7+
- id: ruff-format

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
</a>
1212
</p>
1313

14-
[Codeflash](https://www.codeflash.ai) is a general purpose optimizer for Python that automatically improves the performance of your Python code while maintaining its correctness.
14+
[Codeflash](https://www.codeflash.ai) is a general purpose optimizer for Python that helps you improve the performance of your Python code while maintaining its correctness.
1515
It uses advanced LLMs to generate multiple optimization ideas for your code, tests them to be correct and benchmarks them for performance. It then creates merge-ready pull requests containing the best optimization found, which you can review and merge.
1616

1717
How to use Codeflash -
1818
- Optimize an entire existing codebase by running `codeflash --all`
1919
- Automate optimizing all __future__ code you will write by installing Codeflash as a GitHub action.
20-
- Optimize a Python workflow end-to-end by tracing the workflow.
20+
- Optimize a Python workflow `python myscript.py` end-to-end by running `python -m codeflash.tracer -o benchmark.trace myscript.py`
2121

2222
Codeflash is used by top engineering teams at [Pydantic](https://github.com/pydantic/pydantic/pulls?q=is%3Apr+author%3Amisrasaurabh1+is%3Amerged), [Langflow](https://github.com/langflow-ai/langflow/issues?q=state%3Aclosed%20is%3Apr%20author%3Amisrasaurabh1), [Albumentations](https://github.com/albumentations-team/albumentations/issues?q=state%3Amerged%20is%3Apr%20author%3Akrrt7%20OR%20state%3Amerged%20is%3Apr%20author%3Aaseembits93%20) and many others to ship performant, expert level code.
2323

code_to_optimize/code_directories/simple_tracer_e2e/workload.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33

44
def funcA(number):
5+
number = number if number < 1000 else 1000
56
k = 0
67
for i in range(number * 100):
78
k += i

codeflash/api/aiservice.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import json
44
import os
55
import platform
6+
import time
67
from typing import TYPE_CHECKING, Any
78

89
import requests
@@ -72,7 +73,7 @@ def make_ai_service_request(
7273
# response.raise_for_status() # Will raise an HTTPError if the HTTP request returned an unsuccessful status code
7374
return response
7475

75-
def optimize_python_code(
76+
def optimize_python_code( # noqa: D417
7677
self,
7778
source_code: str,
7879
dependency_code: str,
@@ -95,6 +96,7 @@ def optimize_python_code(
9596
- List[OptimizationCandidate]: A list of Optimization Candidates.
9697
9798
"""
99+
start_time = time.perf_counter()
98100
payload = {
99101
"source_code": source_code,
100102
"dependency_code": dependency_code,
@@ -118,6 +120,8 @@ def optimize_python_code(
118120
optimizations_json = response.json()["optimizations"]
119121
logger.info(f"Generated {len(optimizations_json)} candidates.")
120122
console.rule()
123+
end_time = time.perf_counter()
124+
logger.debug(f"Generating optimizations took {end_time - start_time:.2f} seconds.")
121125
return [
122126
OptimizedCandidate(
123127
source_code=opt["source_code"],
@@ -135,7 +139,7 @@ def optimize_python_code(
135139
console.rule()
136140
return []
137141

138-
def optimize_python_code_line_profiler(
142+
def optimize_python_code_line_profiler( # noqa: D417
139143
self,
140144
source_code: str,
141145
dependency_code: str,
@@ -172,7 +176,7 @@ def optimize_python_code_line_profiler(
172176

173177
logger.info("Generating optimized candidates…")
174178
console.rule()
175-
if line_profiler_results=="":
179+
if line_profiler_results == "":
176180
logger.info("No LineProfiler results were provided, Skipping optimization.")
177181
console.rule()
178182
return []
@@ -204,8 +208,7 @@ def optimize_python_code_line_profiler(
204208
console.rule()
205209
return []
206210

207-
208-
def log_results(
211+
def log_results( # noqa: D417
209212
self,
210213
function_trace_id: str,
211214
speedup_ratio: dict[str, float | None] | None,
@@ -237,7 +240,7 @@ def log_results(
237240
except requests.exceptions.RequestException as e:
238241
logger.exception(f"Error logging features: {e}")
239242

240-
def generate_regression_tests(
243+
def generate_regression_tests( # noqa: D417
241244
self,
242245
source_code_being_tested: str,
243246
function_to_optimize: FunctionToOptimize,
@@ -304,7 +307,7 @@ def generate_regression_tests(
304307
error = response.json()["error"]
305308
logger.error(f"Error generating tests: {response.status_code} - {error}")
306309
ph("cli-testgen-error-response", {"response_status_code": response.status_code, "error": error})
307-
return None
310+
return None # noqa: TRY300
308311
except Exception:
309312
logger.error(f"Error generating tests: {response.status_code} - {response.text}")
310313
ph("cli-testgen-error-response", {"response_status_code": response.status_code, "error": response.text})

codeflash/api/cfapi.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ def suggest_changes(
117117
"existingTests": existing_tests,
118118
"generatedTests": generated_tests,
119119
"traceId": trace_id,
120-
"coverage": coverage_message,
120+
"coverage_message": coverage_message,
121121
}
122122
return make_cfapi_request(endpoint="/suggest-pr-changes", method="POST", payload=payload)
123123

@@ -153,7 +153,7 @@ def create_pr(
153153
"existingTests": existing_tests,
154154
"generatedTests": generated_tests,
155155
"traceId": trace_id,
156-
"coverage": coverage_message,
156+
"coverage_message": coverage_message,
157157
}
158158
return make_cfapi_request(endpoint="/create-pr", method="POST", payload=payload)
159159

@@ -181,19 +181,10 @@ def get_blocklisted_functions() -> dict[str, set[str]] | dict[str, Any]:
181181
if pr_number is None:
182182
return {}
183183

184-
not_found = 404
185-
internal_server_error = 500
186-
187184
owner, repo = get_repo_owner_and_name()
188185
information = {"pr_number": pr_number, "repo_owner": owner, "repo_name": repo}
189186
try:
190187
req = make_cfapi_request(endpoint="/verify-existing-optimizations", method="POST", payload=information)
191-
if req.status_code == not_found:
192-
logger.debug(req.json()["message"])
193-
return {}
194-
if req.status_code == internal_server_error:
195-
logger.error(req.json()["message"])
196-
return {}
197188
req.raise_for_status()
198189
content: dict[str, list[str]] = req.json()
199190
except Exception as e:

codeflash/benchmarking/codeflash_trace.py

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import sqlite3
55
import threading
66
import time
7-
from typing import Callable
7+
from typing import Any, Callable
88

99
from codeflash.picklepatch.pickle_patcher import PicklePatcher
1010

@@ -69,7 +69,7 @@ def write_function_timings(self) -> None:
6969
"(function_name, class_name, module_name, file_path, benchmark_function_name, "
7070
"benchmark_module_path, benchmark_line_number, function_time_ns, overhead_time_ns, args, kwargs) "
7171
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
72-
self.function_calls_data
72+
self.function_calls_data,
7373
)
7474
self._connection.commit()
7575
self.function_calls_data = []
@@ -100,9 +100,10 @@ def __call__(self, func: Callable) -> Callable:
100100
The wrapped function
101101
102102
"""
103-
func_id = (func.__module__,func.__name__)
103+
func_id = (func.__module__, func.__name__)
104+
104105
@functools.wraps(func)
105-
def wrapper(*args, **kwargs):
106+
def wrapper(*args, **kwargs) -> Any: # noqa: ANN002, ANN003, ANN401
106107
# Initialize thread-local active functions set if it doesn't exist
107108
if not hasattr(self._thread_local, "active_functions"):
108109
self._thread_local.active_functions = set()
@@ -139,9 +140,19 @@ def wrapper(*args, **kwargs):
139140
self._thread_local.active_functions.remove(func_id)
140141
overhead_time = time.thread_time_ns() - end_time
141142
self.function_calls_data.append(
142-
(func.__name__, class_name, func.__module__, func.__code__.co_filename,
143-
benchmark_function_name, benchmark_module_path, benchmark_line_number, execution_time,
144-
overhead_time, None, None)
143+
(
144+
func.__name__,
145+
class_name,
146+
func.__module__,
147+
func.__code__.co_filename,
148+
benchmark_function_name,
149+
benchmark_module_path,
150+
benchmark_line_number,
151+
execution_time,
152+
overhead_time,
153+
None,
154+
None,
155+
)
145156
)
146157
return result
147158

@@ -155,9 +166,19 @@ def wrapper(*args, **kwargs):
155166
self._thread_local.active_functions.remove(func_id)
156167
overhead_time = time.thread_time_ns() - end_time
157168
self.function_calls_data.append(
158-
(func.__name__, class_name, func.__module__, func.__code__.co_filename,
159-
benchmark_function_name, benchmark_module_path, benchmark_line_number, execution_time,
160-
overhead_time, None, None)
169+
(
170+
func.__name__,
171+
class_name,
172+
func.__module__,
173+
func.__code__.co_filename,
174+
benchmark_function_name,
175+
benchmark_module_path,
176+
benchmark_line_number,
177+
execution_time,
178+
overhead_time,
179+
None,
180+
None,
181+
)
161182
)
162183
return result
163184
# Flush to database every 100 calls
@@ -168,12 +189,24 @@ def wrapper(*args, **kwargs):
168189
self._thread_local.active_functions.remove(func_id)
169190
overhead_time = time.thread_time_ns() - end_time
170191
self.function_calls_data.append(
171-
(func.__name__, class_name, func.__module__, func.__code__.co_filename,
172-
benchmark_function_name, benchmark_module_path, benchmark_line_number, execution_time,
173-
overhead_time, pickled_args, pickled_kwargs)
192+
(
193+
func.__name__,
194+
class_name,
195+
func.__module__,
196+
func.__code__.co_filename,
197+
benchmark_function_name,
198+
benchmark_module_path,
199+
benchmark_line_number,
200+
execution_time,
201+
overhead_time,
202+
pickled_args,
203+
pickled_kwargs,
204+
)
174205
)
175206
return result
207+
176208
return wrapper
177209

210+
178211
# Create a singleton instance
179212
codeflash_trace = CodeflashTrace()

0 commit comments

Comments
 (0)