Skip to content

Commit

Permalink
Add support for uploading to GCS
Browse files Browse the repository at this point in the history
  • Loading branch information
nielsvanspauwen committed Jun 15, 2023
1 parent 40dc5d5 commit 30f7d8a
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 33 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ build/

# Miscellaneous
.DS_Store

# Credentials
gcs_credentials.json
67 changes: 34 additions & 33 deletions pystructurizr/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
import os
import shutil
import subprocess
from .cli_helper import generate_diagram_code, generate_diagram_code_in_child_process
from google.cloud import storage
from google.cloud.exceptions import GoogleCloudError
from .cli_helper import generate_diagram_code, generate_diagram_code_in_child_process, generate_svg, ensure_tmp_folder_exists
from .cli_watcher import observe_modules


Expand All @@ -15,43 +17,26 @@
@click.option('--view', prompt='Your view file (e.g. example.componentview)',
help='The view file to generate.')
def dump(view):
initial_modules = set(sys.modules.keys())
diagram_code = generate_diagram_code(view)
current_modules = set(sys.modules.keys())
# print("Imported modules:")
# print(current_modules - initial_modules)
click.echo(diagram_code)




@click.command()
@click.option('--view', prompt='Your view file (e.g. example.componentview)',
help='The view file to develop.')
def dev(view):
click.echo(f"Setting up live preview of view {view}...")
# Prep the /tmp/pystructurizr folder
tmp_folder = "/tmp/pystructurizr"
os.makedirs(tmp_folder, exist_ok=True)
tmp_folder = ensure_tmp_folder_exists()
current_script_path = os.path.abspath(__file__)
index_html = os.path.join(os.path.dirname(current_script_path), 'index.html')
print(index_html)
shutil.copy(index_html, f"{tmp_folder}/index.html")

async def async_behavior():
print("Generating diagram...")
diagram_code = generate_diagram_code_in_child_process(view)
# print(diagram_code)
url = f"https://kroki.io/structurizr/svg"

async with httpx.AsyncClient() as client:
resp = await client.post(url, data=diagram_code)
if resp.status_code != 200:
print(resp)
if resp.content:
print(resp.content.decode())
raise click.ClickException("Failed to create diagram")
async with aiofiles.open(f"{tmp_folder}/diagram.svg", "w") as f:
await f.write(resp.text)
print(f"Updated SVG in {tmp_folder}")
await generate_svg(diagram_code, tmp_folder)

async def observe_loop():
await async_behavior()
Expand All @@ -62,25 +47,41 @@ async def observe_loop():
asyncio.run(observe_loop())



@click.command()
@click.option('--view', prompt='Your view file (e.g. example.componentview)',
help='The view file to generate and upload to S3.')
def build(view):
click.echo(f"Generating view {view} and uploading to S3...")
diagram_code = generate_diagram_code(view)
help='The view file to generate and upload to cloud storage.')
@click.option('--gcs-credentials', prompt='Path to json file containing Google Cloud Storage credentials', type=click.Path(exists=True),
help='Path to the credentials.json file for Google Cloud Storage.')
@click.option('--bucket-name', prompt='Name of the bucket on Google Cloud Storage',
help='The name of the bucket to use on Google Cloud Storage.')
@click.option('--object-name', prompt='Name of the object on Google Cloud Storage',
help='The name of the object to use on Google Cloud Storage.')
def build(view, gcs_credentials, bucket_name, object_name):
click.echo(f"Generating view {view} and uploading to cloud storage...")

async def async_behavior():
async with httpx.AsyncClient() as client:
resp = await client.post(url, data=diagram_code)
if resp.status_code != 200:
print(resp)
raise click.ClickException("Failed to create diagram")

# TODO: take resp.text and upload it to an AVG file in an S3 bucket
print("Generating diagram...")
diagram_code = generate_diagram_code(view)
tmp_folder = ensure_tmp_folder_exists()
svg_file_path = await generate_svg(diagram_code, tmp_folder)
try:
print(f"Uploading {svg_file_path}...")
gcs_client = storage.Client.from_service_account_json(gcs_credentials)
gcs_bucket = gcs_client.get_bucket(bucket_name)
gcs_blob = gcs_bucket.blob(object_name)
gcs_blob.upload_from_filename(svg_file_path)
svg_file_url = f"https://storage.googleapis.com/{bucket_name}/{object_name}"
print("Done! You can get the SVG file at:")
print(svg_file_url)
except GoogleCloudError as e:
print("An error occurred while uploading the file to Google Cloud Storage:")
print(e)

asyncio.run(async_behavior())



@click.group()
def cli():
pass
Expand Down
30 changes: 30 additions & 0 deletions pystructurizr/cli_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@
import importlib
import subprocess
import sys
import aiofiles
import click
import httpx
import sys
import os


# This is useally run within the same process as cli.py
# But for the 'dev' command, we run it as a separate process, so it can be run
# repeatedly within the same dev session whenever the view changes.
Expand All @@ -26,3 +31,28 @@ def run_child_process():
# Run the child process and capture its output
child_output = run_child_process()
return child_output


async def generate_svg(diagram_code, tmp_folder):
url = f"https://kroki.io/structurizr/svg"
async with httpx.AsyncClient() as client:
resp = await client.post(url, data=diagram_code)

if resp.status_code != 200:
print(resp)
if resp.content:
print(resp.content.decode())
raise click.ClickException("Failed to create diagram")

svg_file_path = f"{tmp_folder}/diagram.svg"
async with aiofiles.open(svg_file_path, "w") as f:
await f.write(resp.text)
print(f"Updated SVG in {tmp_folder}")

return svg_file_path


def ensure_tmp_folder_exists():
tmp_folder = "/tmp/pystructurizr"
os.makedirs(tmp_folder, exist_ok=True)
return tmp_folder
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ click
httpx
aiofiles
httpwatcher
google-cloud-storage

0 comments on commit 30f7d8a

Please sign in to comment.