devcontainer setup
This commit is contained in:
@@ -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"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
SPECKLE_TOKEN=mytoken
|
||||
Vendored
+11
-5
@@ -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\"}"
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+7
-1
@@ -1,3 +1,9 @@
|
||||
{
|
||||
"cSpell.words": ["camelcase", "pydantic", "stringcase", "typer"]
|
||||
"cSpell.words": [
|
||||
"camelcase",
|
||||
"pydantic",
|
||||
"stringcase",
|
||||
"typer"
|
||||
],
|
||||
"python.defaultInterpreterPath": ".venv/bin/python"
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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": {}}},
|
||||
},
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -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=())
|
||||
Reference in New Issue
Block a user