OpenSCAD and CadQuery working together in dev

Still clean up of the backend/lamdas, and there's a conda permission
issue when deploying the Cadquery image
This commit is contained in:
Kurt Hutten
2021-04-18 17:46:03 +10:00
parent 7733694032
commit 35d5c02f96
9 changed files with 60 additions and 90 deletions

View File

@@ -1,7 +1,6 @@
const express = require('express') const express = require('express')
var cors = require('cors') var cors = require('cors')
const axios = require('axios') const axios = require('axios')
const stream = require('stream')
const app = express() const app = express()
const port = 8080 const port = 8080
app.use(express.json()) app.use(express.json())
@@ -10,14 +9,14 @@ app.use(cors())
const invocationURL = (port) => const invocationURL = (port) =>
`http://localhost:${port}/2015-03-31/functions/function/invocations` `http://localhost:${port}/2015-03-31/functions/function/invocations`
app.post('/render', async (req, res) => { app.post('/openscad/preview', async (req, res) => {
const { data } = await axios.post(invocationURL(5052), { const { data } = await axios.post(invocationURL(5052), {
body: Buffer.from(JSON.stringify(req.body)).toString('base64'), body: Buffer.from(JSON.stringify(req.body)).toString('base64'),
}) })
res.status(data.statusCode) res.status(data.statusCode)
res.send(data.body) res.send(data.body)
}) })
app.post('/cadquery', async (req, res) => { app.post('/cadquery/stl', async (req, res) => {
console.log('making post request to 5060') console.log('making post request to 5060')
const { data } = await axios.post(invocationURL(5060), { const { data } = await axios.post(invocationURL(5060), {
body: Buffer.from(JSON.stringify(req.body)).toString('base64'), body: Buffer.from(JSON.stringify(req.body)).toString('base64'),

View File

@@ -1,15 +1,7 @@
const { runScad, stlExport } = require('./runScad') const { runCQ } = require('./runCQ')
const middy = require('middy') const middy = require('middy')
const { cors } = require('middy/middlewares') const { cors } = require('middy/middlewares')
const health = async () => {
console.log('Health endpoint')
return {
statusCode: 200,
body: 'ok',
}
}
// cors true does not seem to work in serverless.yml, perhaps docker lambdas aren't covered by that config // cors true does not seem to work in serverless.yml, perhaps docker lambdas aren't covered by that config
// special lambda just for responding to options requests // special lambda just for responding to options requests
const preflightOptions = (req, _context, callback) => { const preflightOptions = (req, _context, callback) => {
@@ -24,12 +16,12 @@ const preflightOptions = (req, _context, callback) => {
callback(null, response) callback(null, response)
} }
const render = async (req, _context, callback) => { const stl = async (req, _context, callback) => {
_context.callbackWaitsForEmptyEventLoop = false _context.callbackWaitsForEmptyEventLoop = false
const eventBody = Buffer.from(req.body, 'base64').toString('ascii') const eventBody = Buffer.from(req.body, 'base64').toString('ascii')
console.log(eventBody, 'eventBody') console.log(eventBody, 'eventBody')
const { file, settings } = JSON.parse(eventBody) const { file, settings } = JSON.parse(eventBody)
const { error, result, tempFile } = await runScad({ file, settings }) const { error, result, tempFile } = await runCQ({ file, settings })
if (error) { if (error) {
const response = { const response = {
statusCode: 400, statusCode: 400,
@@ -55,41 +47,7 @@ const render = async (req, _context, callback) => {
} }
} }
const exportstl = async (req, _context, callback) => {
_context.callbackWaitsForEmptyEventLoop = false
const eventBody = Buffer.from(req.body, 'base64').toString('ascii')
console.log(eventBody, 'eventBody')
const { file } = JSON.parse(eventBody)
const { error, result, tempFile } = await stlExport({ file })
if (error) {
const response = {
statusCode: 400,
body: { error, tempFile },
}
callback(null, response)
} else {
console.log(`got result in route: ${result}, file is: ${tempFile}`)
const fs = require('fs')
const stl = fs.readFileSync(`/tmp/${tempFile}/output.stl`, {
encoding: 'base64',
})
console.log('encoded stl', stl)
const response = {
statusCode: 200,
headers: {
'content-type': 'application/stl',
},
body: stl,
isBase64Encoded: true,
}
console.log('callback fired')
callback(null, response)
}
}
module.exports = { module.exports = {
health: middy(health).use(cors()), stl: middy(stl).use(cors()),
exportstl: middy(exportstl).use(cors()),
render: middy(render).use(cors()),
preflightOptions, preflightOptions,
} }

View File

@@ -3,7 +3,7 @@ const { promises } = require('fs')
const { writeFile } = promises const { writeFile } = promises
const { nanoid } = require('nanoid') const { nanoid } = require('nanoid')
module.exports.runScad = async ({ module.exports.runCQ = async ({
file, file,
settings: { settings: {
size: { x = 500, y = 500 } = {}, size: { x = 500, y = 500 } = {},
@@ -29,20 +29,6 @@ module.exports.runScad = async ({
} }
} }
module.exports.stlExport = async ({ file } = {}) => {
const tempFile = await makeFile(file)
try {
const result = await runCommand(
`openscad -o /tmp/${tempFile}/output.stl /tmp/${tempFile}/main.scad`,
300000 // lambda will time out before this, we might need to look at background jobs if we do git integration stl generation
)
return { result, tempFile }
} catch (error) {
return { error, tempFile }
}
}
async function makeFile(file) { async function makeFile(file) {
const tempFile = 'a' + nanoid() // 'a' ensure nothing funny happens if it start with a bad character like "-", maybe I should pick a safer id generator :shrug: const tempFile = 'a' + nanoid() // 'a' ensure nothing funny happens if it start with a bad character like "-", maybe I should pick a safer id generator :shrug:
console.log(`file to write: ${file}`) console.log(`file to write: ${file}`)

View File

@@ -13,25 +13,25 @@ services:
ports: ports:
- "5051:8080" - "5051:8080"
openscad-render: openscad-preview:
image: openscad image: openscad
# build: ./openscad/. # build: ./openscad/.
command: openscad.render command: openscad.preview
# networks: # networks:
# - awsland # - awsland
ports: ports:
- "5052:8080" - "5052:8080"
openscad-export: openscad-stl:
image: openscad image: openscad
# build: ./openscad/. # build: ./openscad/.
command: openscad.exportstl command: openscad.stl
ports: ports:
- "5053:8080" - "5053:8080"
cadquery-render: cadquery-stl:
build: ./cadquery/. build: ./cadquery/.
command: openscad.render command: cadquery.stl
ports: ports:
- 5060:8080 - 5060:8080

View File

@@ -24,7 +24,7 @@ const preflightOptions = (req, _context, callback) => {
callback(null, response) callback(null, response)
} }
const render = async (req, _context, callback) => { const preview = async (req, _context, callback) => {
_context.callbackWaitsForEmptyEventLoop = false _context.callbackWaitsForEmptyEventLoop = false
const eventBody = Buffer.from(req.body, 'base64').toString('ascii') const eventBody = Buffer.from(req.body, 'base64').toString('ascii')
console.log(eventBody, 'eventBody') console.log(eventBody, 'eventBody')
@@ -55,7 +55,7 @@ const render = async (req, _context, callback) => {
} }
} }
const exportstl = async (req, _context, callback) => { const stl = async (req, _context, callback) => {
_context.callbackWaitsForEmptyEventLoop = false _context.callbackWaitsForEmptyEventLoop = false
const eventBody = Buffer.from(req.body, 'base64').toString('ascii') const eventBody = Buffer.from(req.body, 'base64').toString('ascii')
console.log(eventBody, 'eventBody') console.log(eventBody, 'eventBody')
@@ -89,7 +89,7 @@ const exportstl = async (req, _context, callback) => {
module.exports = { module.exports = {
health: middy(health).use(cors()), health: middy(health).use(cors()),
exportstl: middy(exportstl).use(cors()), stl: middy(stl).use(cors()),
render: middy(render).use(cors()), preview: middy(preview).use(cors()),
preflightOptions, preflightOptions,
} }

View File

@@ -18,6 +18,8 @@ provider:
# this image is built locally and push to ECR # this image is built locally and push to ECR
openscadimage: openscadimage:
path: ./openscad/ path: ./openscad/
cadqueryimage:
path: ./cadquery/
apiGateway: apiGateway:
metrics: true metrics: true
binaryMediaTypes: binaryMediaTypes:
@@ -52,7 +54,7 @@ provider:
functions: functions:
# see preflightoptions comment in openscad.js # see preflightoptions comment in openscad.js
preflightrender: preflightopenscadpreview:
image: image:
name: openscadimage name: openscadimage
command: command:
@@ -61,9 +63,9 @@ functions:
- '/entrypoint.sh' - '/entrypoint.sh'
events: events:
- http: - http:
path: render path: openscad/preview
method: options method: options
preflightexport: preflightopenscadstl:
image: image:
name: openscadimage name: openscadimage
command: command:
@@ -72,30 +74,54 @@ functions:
- '/entrypoint.sh' - '/entrypoint.sh'
events: events:
- http: - http:
path: export path: openscad/stl
method: options method: options
render: openscadpreview:
image: image:
name: openscadimage name: openscadimage
command: command:
- openscad.render - openscad.preview
entryPoint: entryPoint:
- '/entrypoint.sh' - '/entrypoint.sh'
events: events:
- http: - http:
path: render path: openscad/preview
method: post method: post
timeout: 15 timeout: 15
exportStl: openscadstl:
image: image:
name: openscadimage name: openscadimage
command: command:
- openscad.exportstl - openscad.stl
entryPoint: entryPoint:
- '/entrypoint.sh' - '/entrypoint.sh'
events: events:
- http: - http:
path: export path: openscad/stl
method: post
timeout: 30
preflightcadquerystl:
image:
name: cadqueryimage
command:
- cadquery.preflightOptions
entryPoint:
- '/entrypoint.sh'
events:
- http:
path: cadquery/stl
method: options
cadquerystl:
image:
name: cadqueryimage
command:
- cadquery.stl
entryPoint:
- '/entrypoint.sh'
events:
- http:
path: cadquery/stl
method: post method: post
timeout: 30 timeout: 30
# The following are a few example events you can configure # The following are a few example events you can configure

View File

@@ -1,4 +1,4 @@
let openScadBaseURL = process.env.CADQUERY_BASE_URL import { lambdaBaseURL } from './common'
export const render = async ({ code }) => { export const render = async ({ code }) => {
const body = JSON.stringify({ const body = JSON.stringify({
@@ -6,7 +6,7 @@ export const render = async ({ code }) => {
file: code, file: code,
}) })
try { try {
const response = await fetch(openScadBaseURL, { const response = await fetch(lambdaBaseURL + '/cadquery/stl', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',

View File

@@ -0,0 +1,3 @@
export const lambdaBaseURL =
process.env.CAD_LAMBDA_BASE_URL ||
'https://t7wdlz8ztf.execute-api.us-east-1.amazonaws.com/dev2'

View File

@@ -1,6 +1,4 @@
let openScadBaseURL = import { lambdaBaseURL } from './common'
process.env.OPENSCAD_BASE_URL ||
'https://x2wvhihk56.execute-api.us-east-1.amazonaws.com/dev'
export const render = async ({ code, settings }) => { export const render = async ({ code, settings }) => {
const pixelRatio = window.devicePixelRatio || 1 const pixelRatio = window.devicePixelRatio || 1
@@ -16,7 +14,7 @@ export const render = async ({ code, settings }) => {
file: code, file: code,
}) })
try { try {
const response = await fetch(openScadBaseURL + '/render', { const response = await fetch(lambdaBaseURL + '/openscad/preview', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',