Skip to content

Commit 36ce900

Browse files
Merge branch 'master' into docs/update-workflows-custom-error-handling
2 parents 3774e18 + 0cde341 commit 36ce900

File tree

98 files changed

+2741
-128
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+2741
-128
lines changed

.github/workflows/pull-request-checks.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
done
3636
3737
echo "files=${files}" >> $GITHUB_ENV
38-
- uses: rojopolis/spellcheck-github-actions@0.38.0
38+
- uses: rojopolis/spellcheck-github-actions@0.40.0
3939
name: Spellcheck
4040
if: ${{ env.files }}
4141
with:

blog/pi/poetry.lock

Lines changed: 206 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

blog/pi/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ snowflake-connector-python = "^3.0.2"
2222
openapi3-parser = "^1.1.6"
2323
plotly = "^5.14.0"
2424
scikit-learn = "^1.5.0"
25-
torch = "^2.0.0"
25+
torch = "^2.2.0"
2626
matplotlib = "^3.7.1"
2727
scikit-optimize = "^0.9.0"
2828
supabase = "^1.2.0"

components/appointo/appointo.app.mjs

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,78 @@
1+
import { axios } from "@pipedream/platform";
2+
import constants from "./common/constants.mjs";
3+
import utils from "./common/utils.mjs";
4+
15
export default {
26
type: "app",
37
app: "appointo",
4-
propDefinitions: {},
58
methods: {
6-
// this.$auth contains connected account data
7-
authKeys() {
8-
console.log(Object.keys(this.$auth));
9+
getUrl(path) {
10+
return `${constants.BASE_URL}${constants.VERSION_PATH}${path}`;
11+
},
12+
getHeaders(headers) {
13+
return {
14+
...headers,
15+
"APPOINTO-TOKEN": `${this.$auth.api_key}`,
16+
};
17+
},
18+
_makeRequest({
19+
$ = this, path, headers, ...args
20+
} = {}) {
21+
return axios($, {
22+
...args,
23+
url: this.getUrl(path),
24+
headers: this.getHeaders(headers),
25+
});
26+
},
27+
listBookings(args = {}) {
28+
return this._makeRequest({
29+
path: "/bookings",
30+
...args,
31+
});
32+
},
33+
async *getIterations({
34+
resourcesFn, resourcesFnArgs,
35+
max = constants.DEFAULT_MAX,
36+
}) {
37+
let offset = 0;
38+
let resourcesCount = 0;
39+
40+
while (true) {
41+
const nextResources =
42+
await resourcesFn({
43+
...resourcesFnArgs,
44+
params: {
45+
...resourcesFnArgs?.params,
46+
limit: constants.DEFAULT_LIMIT,
47+
offset,
48+
},
49+
});
50+
51+
if (!nextResources?.length) {
52+
console.log("No more resources found");
53+
return;
54+
}
55+
56+
for (const resource of nextResources) {
57+
yield resource;
58+
resourcesCount += 1;
59+
60+
if (resourcesCount >= max) {
61+
console.log("Reached max resources");
62+
return;
63+
}
64+
}
65+
66+
if (nextResources.length < constants.DEFAULT_LIMIT) {
67+
console.log("No next page found");
68+
return;
69+
}
70+
71+
offset += constants.DEFAULT_LIMIT;
72+
}
73+
},
74+
paginate(args = {}) {
75+
return utils.iterate(this.getIterations(args));
976
},
1077
},
11-
};
78+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const BASE_URL = "https://app.appointo.me";
2+
const VERSION_PATH = "/api";
3+
const DEFAULT_LIMIT = 100;
4+
const DEFAULT_MAX = 600;
5+
6+
export default {
7+
BASE_URL,
8+
VERSION_PATH,
9+
DEFAULT_LIMIT,
10+
DEFAULT_MAX,
11+
};

components/appointo/common/utils.mjs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
async function iterate(iterations) {
2+
const items = [];
3+
for await (const item of iterations) {
4+
items.push(item);
5+
}
6+
return items;
7+
}
8+
9+
export default {
10+
iterate,
11+
};

components/appointo/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pipedream/appointo",
3-
"version": "0.0.1",
3+
"version": "0.1.0",
44
"description": "Pipedream Appointo Components",
55
"main": "appointo.app.mjs",
66
"keywords": [
@@ -11,5 +11,8 @@
1111
"author": "Pipedream <[email protected]> (https://pipedream.com/)",
1212
"publishConfig": {
1313
"access": "public"
14+
},
15+
"dependencies": {
16+
"@pipedream/platform": "^3.0.0"
1417
}
15-
}
18+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import {
2+
ConfigurationError,
3+
DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
4+
} from "@pipedream/platform";
5+
import app from "../../appointo.app.mjs";
6+
7+
export default {
8+
props: {
9+
app,
10+
timer: {
11+
type: "$.interface.timer",
12+
label: "Polling Schedule",
13+
description: "How often to poll the API",
14+
default: {
15+
intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
16+
},
17+
},
18+
},
19+
methods: {
20+
generateMeta() {
21+
throw new ConfigurationError("generateMeta is not implemented");
22+
},
23+
isResourceRelevant() {
24+
return true;
25+
},
26+
getResourcesFn() {
27+
throw new ConfigurationError("getResourcesFn is not implemented");
28+
},
29+
getResourcesFnArgs() {
30+
throw new ConfigurationError("getResourcesFnArgs is not implemented");
31+
},
32+
processResource(resource) {
33+
const meta = this.generateMeta(resource);
34+
this.$emit(resource, meta);
35+
},
36+
async processResources(resources) {
37+
const {
38+
isResourceRelevant,
39+
processResource,
40+
} = this;
41+
42+
Array.from(resources)
43+
.filter(isResourceRelevant)
44+
.forEach(processResource);
45+
},
46+
},
47+
async run() {
48+
const {
49+
app,
50+
getResourcesFn,
51+
getResourcesFnArgs,
52+
processResources,
53+
} = this;
54+
55+
const resources = await app.paginate({
56+
resourcesFn: getResourcesFn(),
57+
resourcesFnArgs: getResourcesFnArgs(),
58+
});
59+
60+
processResources(resources);
61+
},
62+
};
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import common from "../common/polling.mjs";
2+
3+
export default {
4+
...common,
5+
key: "appointo-new-booking-created",
6+
name: "New Booking Created",
7+
description: "Emit new event when a booking is created in Appointo. [See the documentation](https://api-docs.appointo.me/reference/api-reference/bookings)",
8+
version: "0.0.1",
9+
type: "source",
10+
dedupe: "unique",
11+
methods: {
12+
...common.methods,
13+
isResourceRelevant(resource) {
14+
return Array.isArray(resource.customers) && resource.customers.length > 0;
15+
},
16+
getResourcesFn() {
17+
return this.app.listBookings;
18+
},
19+
getResourcesFnArgs() {
20+
return {
21+
debug: true,
22+
};
23+
},
24+
generateMeta(resource) {
25+
return {
26+
id: resource.id,
27+
summary: `New Booking: ${resource.id}`,
28+
ts: Date.parse(resource.created_at),
29+
};
30+
},
31+
},
32+
};
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import documerge from "../../documerge.app.mjs";
2+
import fs from "fs";
3+
4+
export default {
5+
key: "documerge-combine-files",
6+
name: "Combine Files",
7+
description: "Merges multiple user-specified files into a single PDF or DOCX. [See the documentation](https://app.documerge.ai/api-docs/#tools-POSTapi-tools-combine)",
8+
version: "0.0.1",
9+
type: "action",
10+
props: {
11+
documerge,
12+
name: {
13+
type: "string",
14+
label: "Name",
15+
description: "Name of the new file",
16+
},
17+
output: {
18+
type: "string",
19+
label: "Output",
20+
description: "The output file type",
21+
options: [
22+
"pdf",
23+
"docx",
24+
],
25+
},
26+
urls: {
27+
type: "string[]",
28+
label: "URLs",
29+
description: "Array of URLs to combine",
30+
},
31+
},
32+
async run({ $ }) {
33+
const fileContent = await this.documerge.combineFiles({
34+
$,
35+
data: {
36+
output: this.output,
37+
files: this.urls.map((url) => ({
38+
name: this.name,
39+
url,
40+
})),
41+
},
42+
});
43+
44+
const filename = this.name.includes(".pdf") || this.name.includes(".docx")
45+
? this.name
46+
: `${this.name}.${this.output}`;
47+
const path = `/tmp/${filename}`;
48+
await fs.writeFileSync(path, Buffer.from(fileContent));
49+
50+
$.export("$summary", "Successfully combined files");
51+
return path;
52+
},
53+
};

0 commit comments

Comments
 (0)