diagram-to-iac 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- diagram_to_iac/__init__.py +0 -0
- diagram_to_iac/agents/__init__.py +0 -0
- diagram_to_iac/agents/codegen_agent.py +0 -0
- diagram_to_iac/agents/consensus_agent.py +0 -0
- diagram_to_iac/agents/github_agent.py +0 -0
- diagram_to_iac/agents/interpretation_agent.py +0 -0
- diagram_to_iac/agents/question_agent.py +0 -0
- diagram_to_iac/agents/supervisor.py +0 -0
- diagram_to_iac/agents/vision_agent.py +0 -0
- diagram_to_iac/cli.py +13 -0
- diagram_to_iac/core/__init__.py +0 -0
- diagram_to_iac/core/agent_base.py +0 -0
- diagram_to_iac/core/config.py +0 -0
- diagram_to_iac/core/memory.py +0 -0
- diagram_to_iac/tools/__init__.py +0 -0
- diagram_to_iac/tools/api_utils.py +109 -0
- diagram_to_iac/tools/cv_utils.py +0 -0
- diagram_to_iac/tools/gh_utils.py +0 -0
- diagram_to_iac/tools/llm_utils/__init__.py +0 -0
- diagram_to_iac/tools/llm_utils/anthropic_driver.py +0 -0
- diagram_to_iac/tools/llm_utils/gemini_driver.py +0 -0
- diagram_to_iac/tools/llm_utils/openai_driver.py +0 -0
- diagram_to_iac/tools/llm_utils/router.py +0 -0
- diagram_to_iac/tools/sec_utils.py +64 -0
- diagram_to_iac/tools/tf_utils.py +0 -0
- diagram_to_iac-0.1.0.dist-info/METADATA +16 -0
- diagram_to_iac-0.1.0.dist-info/RECORD +30 -0
- diagram_to_iac-0.1.0.dist-info/WHEEL +5 -0
- diagram_to_iac-0.1.0.dist-info/entry_points.txt +2 -0
- diagram_to_iac-0.1.0.dist-info/top_level.txt +1 -0
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
diagram_to_iac/cli.py
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# src/diagram_to_iac/cli.py
|
2
|
+
|
3
|
+
import sys, json
|
4
|
+
import requests # external package, so pipreqs must pick it up
|
5
|
+
|
6
|
+
def main():
|
7
|
+
# a sanity check that our imports actually work:
|
8
|
+
print("✅ diagram-to-iac CLI is up and running!")
|
9
|
+
print("• requests version:", requests.__version__)
|
10
|
+
# verify stdlib too
|
11
|
+
data = {"ok": True}
|
12
|
+
print("• json dump:", json.dumps(data))
|
13
|
+
sys.exit(0)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,109 @@
|
|
1
|
+
import sys
|
2
|
+
import os
|
3
|
+
from openai import OpenAI
|
4
|
+
from anthropic import Anthropic
|
5
|
+
import requests
|
6
|
+
import google.generativeai as genai
|
7
|
+
import googleapiclient.discovery
|
8
|
+
# Add the parent directory to sys.path to import env_loader
|
9
|
+
# sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
10
|
+
# from scripts.env_loader import load_env_keys
|
11
|
+
|
12
|
+
def test_openai_api():
|
13
|
+
try:
|
14
|
+
if not os.environ.get("OPENAI_API_KEY"):
|
15
|
+
print("❌ OpenAI API error: OPENAI_API_KEY environment variable not set.")
|
16
|
+
return False
|
17
|
+
client = OpenAI()
|
18
|
+
response = client.chat.completions.create(
|
19
|
+
# Consider using a newer model if appropriate, e.g., "gpt-4o-mini" or "gpt-3.5-turbo"
|
20
|
+
model="gpt-3.5-turbo",
|
21
|
+
messages=[{"role": "user", "content": "Hello, are you working?"}],
|
22
|
+
max_tokens=10
|
23
|
+
)
|
24
|
+
return True
|
25
|
+
except Exception as e:
|
26
|
+
print(f"❌ Open AI API error: {str(e)}")
|
27
|
+
return False
|
28
|
+
|
29
|
+
def test_gemini_api():
|
30
|
+
try:
|
31
|
+
google_api_key = os.environ.get("GOOGLE_API_KEY")
|
32
|
+
if not google_api_key:
|
33
|
+
print("❌ Gemini API error: GOOGLE_API_KEY environment variable not set.")
|
34
|
+
return False
|
35
|
+
genai.configure(api_key=google_api_key)
|
36
|
+
model = genai.GenerativeModel('gemini-1.5-flash-latest') # Corrected model name
|
37
|
+
response = model.generate_content("Hello, are you working?")
|
38
|
+
return True
|
39
|
+
except Exception as e:
|
40
|
+
print(f"❌ Gemini API error: {str(e)}")
|
41
|
+
return False
|
42
|
+
|
43
|
+
def test_anthropic_api():
|
44
|
+
try:
|
45
|
+
if not os.environ.get("ANTHROPIC_API_KEY"):
|
46
|
+
print("❌ Anthropic API error: ANTHROPIC_API_KEY environment variable not set.")
|
47
|
+
return False
|
48
|
+
client = Anthropic()
|
49
|
+
response = client.messages.create(
|
50
|
+
model="claude-3-haiku-20240307",
|
51
|
+
max_tokens=10,
|
52
|
+
messages=[{"role": "user", "content": "Hello, are you working?"}]
|
53
|
+
)
|
54
|
+
return True
|
55
|
+
except Exception as e:
|
56
|
+
print(f"❌ Anthropic API error: {str(e)}")
|
57
|
+
return False
|
58
|
+
|
59
|
+
def test_github_api():
|
60
|
+
"""Test the GitHub API connection."""
|
61
|
+
try:
|
62
|
+
token = os.environ.get("GITHUB_TOKEN")
|
63
|
+
if not token: # This check is already good
|
64
|
+
print("❌ GitHub API error: GITHUB_TOKEN environment variable not set")
|
65
|
+
return False
|
66
|
+
|
67
|
+
headers = {
|
68
|
+
"Authorization": f"Bearer {token}",
|
69
|
+
"Accept": "application/vnd.github.v3+json"
|
70
|
+
}
|
71
|
+
|
72
|
+
# Try to get the authenticated user
|
73
|
+
url = "https://api.github.com/user"
|
74
|
+
response = requests.get(url, headers=headers)
|
75
|
+
|
76
|
+
if response.status_code == 200:
|
77
|
+
user_data = response.json()
|
78
|
+
username = user_data.get('login')
|
79
|
+
print(f"✅ GitHub API works! Authenticated as: {username}")
|
80
|
+
return True
|
81
|
+
else:
|
82
|
+
print(f"❌ GitHub API error: Status code {response.status_code}")
|
83
|
+
return False
|
84
|
+
except Exception as e:
|
85
|
+
print(f"❌ GitHub API error: {str(e)}")
|
86
|
+
return False
|
87
|
+
|
88
|
+
def test_all_apis():
|
89
|
+
print("Hello from the test workflow!")
|
90
|
+
print("Loading environment keys...")
|
91
|
+
# Load environment keys once before running all tests
|
92
|
+
#load_env_keys()
|
93
|
+
|
94
|
+
print("Testing API connections...")
|
95
|
+
openai_success = test_openai_api()
|
96
|
+
gemini_success = test_gemini_api()
|
97
|
+
anthropic_success = test_anthropic_api()
|
98
|
+
github_success = test_github_api() # Added GitHub API test
|
99
|
+
|
100
|
+
print("\nSummary:")
|
101
|
+
print(f"OpenAI API: {'✅ Working' if openai_success else '❌ Failed'}")
|
102
|
+
print(f"Gemini API: {'✅ Working' if gemini_success else '❌ Failed'}")
|
103
|
+
print(f"Anthropic API: {'✅ Working' if anthropic_success else '❌ Failed'}")
|
104
|
+
print(f"GitHub API: {'✅ Working' if github_success else '❌ Failed'}") # Added GitHub API result
|
105
|
+
|
106
|
+
if openai_success and gemini_success and anthropic_success and github_success: # Updated condition
|
107
|
+
print("\n🎉 All APIs are working correctly!")
|
108
|
+
else:
|
109
|
+
print("\n⚠️ Some APIs failed. Check the errors above.")
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# src/diagram_to_iac/tools/secrets.py
|
2
|
+
|
3
|
+
"""
|
4
|
+
Decode /run/secrets.yaml (Base64‑encoded values) into real env vars.
|
5
|
+
|
6
|
+
Mount it into the container with:
|
7
|
+
docker run … -v "$PWD/config/secrets.yaml":/run/secrets.yaml:ro …
|
8
|
+
|
9
|
+
If the file is missing (e.g. CI injects GitHub Secrets directly),
|
10
|
+
load_yaml_secrets() is a no‑op.
|
11
|
+
"""
|
12
|
+
|
13
|
+
import os
|
14
|
+
import base64
|
15
|
+
import yaml
|
16
|
+
import pathlib
|
17
|
+
import binascii
|
18
|
+
|
19
|
+
# Path inside container where the encoded YAML is mounted
|
20
|
+
_YAML_PATH = pathlib.Path("/run/secrets.yaml")
|
21
|
+
|
22
|
+
|
23
|
+
def _decode_b64(enc: str) -> str:
|
24
|
+
"""Robust Base64 decode: fixes padding, falls back if invalid."""
|
25
|
+
enc = enc.strip()
|
26
|
+
if not enc:
|
27
|
+
return ""
|
28
|
+
# Fix missing padding
|
29
|
+
enc += "=" * (-len(enc) % 4)
|
30
|
+
try:
|
31
|
+
return base64.b64decode(enc).decode("utf-8").strip()
|
32
|
+
except (binascii.Error, UnicodeDecodeError):
|
33
|
+
# If it isn’t valid Base64, return the raw string
|
34
|
+
return enc
|
35
|
+
|
36
|
+
|
37
|
+
def load_yaml_secrets() -> None:
|
38
|
+
"""
|
39
|
+
Read /run/secrets.yaml, decode each *_ENCODED value, and export
|
40
|
+
as environment variables. Special‑case REPO_TOKEN → GITHUB_TOKEN.
|
41
|
+
Safe to call when the file does not exist.
|
42
|
+
"""
|
43
|
+
if not _YAML_PATH.exists():
|
44
|
+
return
|
45
|
+
|
46
|
+
data: dict[str, str] = yaml.safe_load(_YAML_PATH.read_text()) or {}
|
47
|
+
for key, encoded in data.items():
|
48
|
+
if not encoded:
|
49
|
+
continue
|
50
|
+
|
51
|
+
# Strip the "_ENCODED" suffix
|
52
|
+
# base_name = key.removesuffix("_ENCODED")
|
53
|
+
|
54
|
+
# GitHub Actions requires the env var "GITHUB_TOKEN"
|
55
|
+
# not "REPO_TOKEN", so map accordingly
|
56
|
+
if key == "REPO_TOKEN":
|
57
|
+
env_name = "GITHUB_TOKEN"
|
58
|
+
else:
|
59
|
+
env_name = key
|
60
|
+
|
61
|
+
# Decode and export
|
62
|
+
plain_value = _decode_b64(str(encoded))
|
63
|
+
os.environ[env_name] = plain_value
|
64
|
+
# print(f"Decoded {env_name}={plain_value}")
|
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: diagram-to-iac
|
3
|
+
Version: 0.1.0
|
4
|
+
Summary: Convert architecture diagrams into IaC modules
|
5
|
+
Author-email: vindpro <admin@vindpro.com>
|
6
|
+
Description-Content-Type: text/markdown
|
7
|
+
Requires-Dist: anthropic==0.51.0
|
8
|
+
Requires-Dist: google_api_python_client==2.169.0
|
9
|
+
Requires-Dist: openai==1.79.0
|
10
|
+
Requires-Dist: protobuf<5.0.0dev,>=3.19.5
|
11
|
+
Requires-Dist: PyYAML==6.0.2
|
12
|
+
Requires-Dist: Requests==2.32.3
|
13
|
+
Requires-Dist: google-generativeai==0.3.1
|
14
|
+
|
15
|
+
# diagram-to-iac
|
16
|
+
an automated system that intelligently translates visual cloud infrastructure diagrams (specifically Azure) into deployable Infrastructure as Code (IaC), leveraging AI for analysis and GitHub for collaborative refinement.
|
@@ -0,0 +1,30 @@
|
|
1
|
+
diagram_to_iac/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
diagram_to_iac/cli.py,sha256=uumG1frF42eCkdLIZxyxQB1x6lDwtG-qKL4vcHnLLXY,400
|
3
|
+
diagram_to_iac/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
+
diagram_to_iac/agents/codegen_agent.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
+
diagram_to_iac/agents/consensus_agent.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
|
+
diagram_to_iac/agents/github_agent.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
|
+
diagram_to_iac/agents/interpretation_agent.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
|
+
diagram_to_iac/agents/question_agent.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
|
+
diagram_to_iac/agents/supervisor.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
|
+
diagram_to_iac/agents/vision_agent.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
|
+
diagram_to_iac/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
12
|
+
diagram_to_iac/core/agent_base.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
|
+
diagram_to_iac/core/config.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
14
|
+
diagram_to_iac/core/memory.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
|
+
diagram_to_iac/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
16
|
+
diagram_to_iac/tools/api_utils.py,sha256=Guq0lJZIc-ds46-2Id80lIOFdbN4vh_dEAM9ONSgS6M,4171
|
17
|
+
diagram_to_iac/tools/cv_utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
|
+
diagram_to_iac/tools/gh_utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
|
+
diagram_to_iac/tools/sec_utils.py,sha256=SJvNk-OWrF-frIVSYiPirnV4m4-ivzFsNrIXz-SVAxM,1845
|
20
|
+
diagram_to_iac/tools/tf_utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
21
|
+
diagram_to_iac/tools/llm_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
|
+
diagram_to_iac/tools/llm_utils/anthropic_driver.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
23
|
+
diagram_to_iac/tools/llm_utils/gemini_driver.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
|
+
diagram_to_iac/tools/llm_utils/openai_driver.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
25
|
+
diagram_to_iac/tools/llm_utils/router.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
26
|
+
diagram_to_iac-0.1.0.dist-info/METADATA,sha256=xqOahnAIgsnWMDfQUlCk3Dn9NZtIa8CaEubCDs9U6sg,693
|
27
|
+
diagram_to_iac-0.1.0.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
|
28
|
+
diagram_to_iac-0.1.0.dist-info/entry_points.txt,sha256=E_krzrW2-_KGXGPWFW9derAqSIQ7WYSd2pwrb7ap4j8,59
|
29
|
+
diagram_to_iac-0.1.0.dist-info/top_level.txt,sha256=k1cV0YODiCUU46qlmbQaquMcbMXhNm05NZLxsinDUBA,15
|
30
|
+
diagram_to_iac-0.1.0.dist-info/RECORD,,
|
@@ -0,0 +1 @@
|
|
1
|
+
diagram_to_iac
|