devcontainer setup

This commit is contained in:
Gergő Jedlicska
2023-08-30 07:41:08 +00:00
parent 02871571c1
commit 9b78af538b
9 changed files with 130 additions and 170 deletions
+43
View File
@@ -0,0 +1,43 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"name": "Python 3",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/python:1-3.11-bullseye",
"features": {
"ghcr.io/devcontainers-contrib/features/poetry:2": {}
},
"remoteEnv": {
"SPECKLE_TOKEN": "foobar"
},
"containerEnv": {
"SPECKLE_TOKEN": "asdfasdf"
},
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "cp .env.example .env && POETRY_VIRTUALENVS_IN_PROJECT=true poetry install --no-root",
// Configure tool-specific properties.
"customizations": {
"vscode": {
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-python.vscode-pylance",
"ms-python.python",
"ms-python.black-formatter",
"streetsidesoftware.code-spell-checker",
"mikestead.dotenv"
]
}
}
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
+1
View File
@@ -0,0 +1 @@
SPECKLE_TOKEN=mytoken
+11 -5
View File
@@ -5,12 +5,18 @@
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"name": "Speckle Automate function",
"type": "python",
"request": "launch",
"program": "${file}",
"program": "main.py",
"console": "integratedTerminal",
"justMyCode": false
}
"justMyCode": true,
"envFile": "${workspaceFolder}/.env",
"args": [
"{\"projectId\": \"843d07eb10\", \"modelId\": \"base design\", \"versionId\": \"2a32ccfee1\", \"speckleServerUrl\": \"https://latest.speckle.systems\"}",
// make sure to use camelCase for variable names
"{\"speckleTypeToCount\": \"Objects.Geometry.Brep\"}"
],
},
]
}
}
+7 -1
View File
@@ -1,3 +1,9 @@
{
"cSpell.words": ["camelcase", "pydantic", "stringcase", "typer"]
"cSpell.words": [
"camelcase",
"pydantic",
"stringcase",
"typer"
],
"python.defaultInterpreterPath": ".venv/bin/python"
}
+45
View File
@@ -0,0 +1,45 @@
from pydantic import BaseModel, ConfigDict
from stringcase import camelcase
from specklepy.transports.memory import MemoryTransport
from specklepy.transports.server import ServerTransport
from specklepy.api.operations import receive
from specklepy.api.client import SpeckleClient
from flatten import flatten_base
from speckle_project_data import SpeckleProjectData
class FunctionInputs(BaseModel):
"""
These are function author defined values, automate will make sure to supply them.
"""
speckle_type_to_count: str
model_config = ConfigDict(alias_generator=camelcase)
def automate_function(
project_data: SpeckleProjectData,
function_inputs: FunctionInputs,
speckle_token: str,
):
client = SpeckleClient(project_data.speckle_server_url)
client.authenticate_with_token(speckle_token)
commit = client.commit.get(project_data.project_id, project_data.version_id)
memory_transport = MemoryTransport()
server_transport = ServerTransport(project_data.project_id, client)
if not commit.referencedObject:
raise ValueError("The commit has no root referencedObject.")
base = receive(commit.referencedObject, server_transport, memory_transport)
count = 0
for b in flatten_base(base):
if b.speckle_type == function_inputs.speckle_type_to_count:
count += 1
print(
f"Found {count} object that match the queried speckle type: ",
"{function_inputs.speckle_type_to_count}",
)
+2 -2
View File
@@ -4,6 +4,6 @@ from specklepy.objects import Base
def flatten_base(base: Base) -> Iterable[Base]:
if hasattr(base, "elements"):
for element in base.elements:
for element in base["elements"]:
yield from flatten_base(element)
yield base
yield base
+8 -59
View File
@@ -1,68 +1,17 @@
import typer
from pydantic import BaseModel, ConfigDict
from stringcase import camelcase
from specklepy.transports.memory import MemoryTransport
from specklepy.transports.server import ServerTransport
from specklepy.api.operations import receive
from specklepy.api.client import SpeckleClient
import random
from flatten import flatten_base
from make_comment import make_comment
import os
from speckle_project_data import SpeckleProjectData
from automate_function import FunctionInputs, automate_function
class SpeckleProjectData(BaseModel):
"""Values of the project / model that triggered the run of this function."""
def main(speckle_project_data: str, function_inputs: str, speckle_token: str = ""):
speckle_token = speckle_token if speckle_token else os.environ.get("SPECKLE_TOKEN")
if not speckle_token:
raise ValueError("The supplied speckle token is not valid")
project_id: str
model_id: str
version_id: str
speckle_server_url: str
model_config = ConfigDict(alias_generator=camelcase, protected_namespaces=())
class FunctionInputs(BaseModel):
"""
These are function author defined values, automate will make sure to supply them.
"""
comment_text: str
class Config:
alias_generator = camelcase
def main(speckle_project_data: str, function_inputs: str, speckle_token: str):
project_data = SpeckleProjectData.model_validate_json(speckle_project_data)
inputs = FunctionInputs.model_validate_json(function_inputs)
client = SpeckleClient(project_data.speckle_server_url, use_ssl=False)
client.authenticate_with_token(speckle_token)
commit = client.commit.get(project_data.project_id, project_data.version_id)
branch = client.branch.get(project_data.project_id, project_data.model_id, 1)
memory_transport = MemoryTransport()
server_transport = ServerTransport(project_data.project_id, client)
base = receive(commit.referencedObject, server_transport, memory_transport)
random_beam = random.choice(
[b for b in flatten_base(base) if b.speckle_type == "IFCBEAM"]
)
make_comment(
client,
project_data.project_id,
branch.id,
project_data.version_id,
inputs.comment_text,
random_beam.id,
)
print(
"Ran function with",
f"{speckle_project_data} {function_inputs}",
)
automate_function(project_data, inputs, speckle_token)
if __name__ == "__main__":
-103
View File
@@ -1,103 +0,0 @@
from specklepy.api.client import SpeckleClient
from gql import gql
def make_comment(
client: SpeckleClient,
project_id: str,
model_id: str,
version_id: str,
comment_text: str,
selected_object_id: str,
) -> None:
client.httpclient.execute(
gql(
"""
mutation createComment($input: CreateCommentInput!) {
commentMutations {
create(input: $input) {
id
}
}
}
"""
),
{
"input": {
"content": {
"blobIds": [],
"doc": {
"content": [
{
"content": [{"text": comment_text, "type": "text"}],
"type": "paragraph",
}
],
"type": "doc",
},
},
"projectId": project_id,
"resourceIdString": model_id,
"screenshot": None,
"viewerState": {
"projectId": project_id,
"resources": {
"request": {
"resourceIdString": f"{model_id}@{version_id}",
"threadFilters": {},
}
},
"sessionId": "fooobarbaz",
"ui": {
"camera": {
"isOrthoProjection": False,
"position": [
-13.959975903859306,
109.21340462426888,
19.00868018548827,
],
"target": [
-28.304303646087646,
99.69336318969727,
2.3997000455856323,
],
"zoom": 1,
},
"explodeFactor": 0,
"filters": {
"hiddenObjectIds": [],
"isolatedObjectIds": [selected_object_id],
"propertyFilter": {"isApplied": False, "key": None},
"selectedObjectIds": [selected_object_id],
},
"lightConfig": {
"azimuth": 0.75,
"castShadow": True,
"color": 16777215,
"elevation": 1.33,
"enabled": True,
"indirectLightIntensity": 1.2,
"intensity": 5,
"radius": 0,
"shadowcatcher": True,
},
"sectionBox": None,
"selection": [
-31.355755138199026,
101.06821903317298,
4.250507316347136,
],
"spotlightUserSessionId": None,
"threads": {
"openThread": {
"isTyping": False,
"newThreadEditor": True,
"threadId": None,
}
},
},
"viewer": {"metadata": {"filteringState": {}}},
},
}
},
)
+13
View File
@@ -0,0 +1,13 @@
from pydantic import BaseModel, ConfigDict
from stringcase import camelcase
class SpeckleProjectData(BaseModel):
"""Values of the project / model that triggered the run of this function."""
project_id: str
model_id: str
version_id: str
speckle_server_url: str
model_config = ConfigDict(alias_generator=camelcase, protected_namespaces=())