├── .yarnrc.yml ├── sample-code ├── azure-blob-text-edit │ ├── .gitignore │ ├── package.json │ ├── README.md │ └── app.js ├── service-principal-sample-app │ ├── .gitignore │ ├── .eslintrc │ ├── package.json │ └── README.md ├── s3-smart-object-replacement │ ├── .gitignore │ ├── package.json │ ├── README.md │ └── app.js ├── webhook-sample-app │ ├── README.md │ └── app.js ├── storage-app │ ├── googledrive │ │ ├── package.json │ │ ├── service-account.json │ │ └── presignedURLs.js │ ├── aws-s3 │ │ ├── presignedURLs.py │ │ ├── presignedURLs.js │ │ └── example.py │ └── azure │ │ ├── presignedURLs.py │ │ └── presignedURLs.js ├── ic-customized-workflow-app │ ├── IC_customized_workflow_using_cc_storage.sh │ └── IC_customized_workflow_using_S3.sh └── lr-sample-app │ └── crs.xml ├── src └── pages │ ├── hero.png │ ├── features │ ├── sensei_mask.png │ ├── sensei_orig.jpg │ ├── preset_example.png │ ├── sensei_cutout.png │ ├── autotone_example.png │ ├── ps_developer_mode.png │ ├── psactions_example.png │ ├── textlayer_example.png │ ├── smartobject_example.png │ ├── ps_action_json_example.png │ ├── imagecutout_mask_example.png │ ├── imagecutout_cutout_example.png │ ├── ps_action_json_example_bw.png │ └── supported-fonts │ │ └── index.md │ ├── getting-started │ ├── images │ │ ├── BuildApp.png │ │ ├── SignUp.png │ │ ├── AddAPIConsole.png │ │ ├── AddAnotherAPI.png │ │ ├── LandingPage.png │ │ ├── TestCredential.png │ │ ├── AccessTokenCurlCmd.png │ │ ├── AddAPIConsoleLRFF.png │ │ ├── AddAPIConsolePSFF.png │ │ ├── AddAPIConsoleRBFF.png │ │ ├── CreateCredential.png │ │ ├── HelloworldCurlCmd.png │ │ ├── SelectAPIConsole.png │ │ ├── GenerateTokenWizard.png │ │ ├── WelcomePhotoshopAPI.png │ │ ├── AccessTokenCurlConsole.png │ │ ├── CreateNewProjectConsole.png │ │ ├── ServicePrincipalConsole.png │ │ └── GenerateAccessTokenFromConsole.png │ └── index.md │ ├── release-notes │ └── index.md │ ├── api │ └── index.md │ ├── support │ └── index.md │ ├── index.md │ └── general-workflow │ └── index.md ├── sample_files ├── Example.jpg ├── Example.psd ├── Sunflower.psd ├── heroImage.png ├── Layer Comps.psd └── ic_customized_workflow │ ├── input.jpg │ ├── make-path.atn │ └── result_with_path.jpg ├── .env.example ├── COPYRIGHT ├── .github ├── super-linter.env ├── dependabot.yml ├── ISSUE_TEMPLATE.md ├── workflows │ ├── deploy.yml │ └── github-pages.yml ├── linters │ ├── .yaml-lint.yml │ └── .markdownlint.yml ├── PULL_REQUEST_TEMPLATE.md ├── scripts │ └── get-path-prefix.js └── CONTRIBUTING.md ├── static ├── acr │ ├── post_auto_tone.schema.json │ ├── api_response_success_schema.json │ ├── post_presets.schema.json │ ├── post_xmp_to_preset.schema.json │ ├── post_mask.schema.json │ ├── post_xmp.schema.json │ ├── post_auto_straighten.schema.json │ ├── inputs.schema.json │ ├── get_status.schema.json │ ├── post_image_edit.schema.json │ └── outputs.schema.json ├── PITS │ ├── preferences.schema.json │ ├── post_social_media_rendition_action.schema.json │ ├── post_rendition_create.schema.json │ ├── post_document_operations.schema.json │ ├── post_artboard_create.schema.json │ ├── api_response_success_schema.json │ ├── post_document_manifest.schema.json │ ├── bounds.schema.json │ ├── post_product_crop_action_json.schema.json │ ├── post_action_json_create.schema.json │ ├── post_layer_brightness_contrast.schema.json │ ├── post_photoshop_actions.schema.json │ ├── layer_options.schema.json │ ├── iccProfile.schema.json │ ├── get_status.schema.json │ ├── post_smart_object.schema.json │ ├── document.schema.json │ ├── get_manifest_status.schema.json │ ├── post_smart_object_v2.schema.json │ ├── file_output_action_json_create.schema.json │ ├── text.schema.json │ ├── fontColor.schema.json │ ├── post_document_create.schema.json │ ├── adjustments.schema.json │ ├── post_depth_blur.schema.json │ ├── file_output_pegasus.schema.json │ ├── file_input.schema.json │ └── post_action_json.schema.json ├── ic │ ├── api_response_success_schema.json │ ├── get_status.schema.json │ └── post_cutout.schema.json ├── api_response_402_error_schema.json ├── api_response_403_error_schema.json ├── api_response_409_error_schema.json ├── api_response_404_error_schema.json ├── api_response_400_error_schema.json └── api_response_410_error_schema.json ├── .gitignore ├── package.json ├── gatsby-config.js ├── README.md └── CODE_OF_CONDUCT.md /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | nodeLinker: node-modules 3 | yarnPath: .yarn/releases/yarn-3.2.1.cjs 4 | -------------------------------------------------------------------------------- /sample-code/azure-blob-text-edit/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | config/private.key 3 | private.key -------------------------------------------------------------------------------- /src/pages/hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/hero.png -------------------------------------------------------------------------------- /sample-code/service-principal-sample-app/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | config.json 3 | private.key 4 | .vscode 5 | -------------------------------------------------------------------------------- /sample-code/s3-smart-object-replacement/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | config/private.key 3 | config 4 | private.key 5 | -------------------------------------------------------------------------------- /sample_files/Example.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/sample_files/Example.jpg -------------------------------------------------------------------------------- /sample_files/Example.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/sample_files/Example.psd -------------------------------------------------------------------------------- /sample-code/service-principal-sample-app/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parserOptions": { 3 | "ecmaVersion": 2017 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /sample_files/Sunflower.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/sample_files/Sunflower.psd -------------------------------------------------------------------------------- /sample_files/heroImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/sample_files/heroImage.png -------------------------------------------------------------------------------- /sample_files/Layer Comps.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/sample_files/Layer Comps.psd -------------------------------------------------------------------------------- /src/pages/features/sensei_mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/features/sensei_mask.png -------------------------------------------------------------------------------- /src/pages/features/sensei_orig.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/features/sensei_orig.jpg -------------------------------------------------------------------------------- /src/pages/features/preset_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/features/preset_example.png -------------------------------------------------------------------------------- /src/pages/features/sensei_cutout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/features/sensei_cutout.png -------------------------------------------------------------------------------- /src/pages/features/autotone_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/features/autotone_example.png -------------------------------------------------------------------------------- /src/pages/features/ps_developer_mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/features/ps_developer_mode.png -------------------------------------------------------------------------------- /src/pages/features/psactions_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/features/psactions_example.png -------------------------------------------------------------------------------- /src/pages/features/textlayer_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/features/textlayer_example.png -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | REPO_GITHUB_TOKEN= 2 | REPO_OWNER=AdobeDocs 3 | REPO_NAME=dev-site-documentation-template 4 | REPO_BRANCH=main 5 | GATSBY_LAUNCH_SRC= 6 | -------------------------------------------------------------------------------- /src/pages/features/smartobject_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/features/smartobject_example.png -------------------------------------------------------------------------------- /sample_files/ic_customized_workflow/input.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/sample_files/ic_customized_workflow/input.jpg -------------------------------------------------------------------------------- /src/pages/features/ps_action_json_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/features/ps_action_json_example.png -------------------------------------------------------------------------------- /src/pages/getting-started/images/BuildApp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/getting-started/images/BuildApp.png -------------------------------------------------------------------------------- /src/pages/getting-started/images/SignUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/getting-started/images/SignUp.png -------------------------------------------------------------------------------- /src/pages/features/imagecutout_mask_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/features/imagecutout_mask_example.png -------------------------------------------------------------------------------- /sample_files/ic_customized_workflow/make-path.atn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/sample_files/ic_customized_workflow/make-path.atn -------------------------------------------------------------------------------- /src/pages/features/imagecutout_cutout_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/features/imagecutout_cutout_example.png -------------------------------------------------------------------------------- /src/pages/features/ps_action_json_example_bw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/features/ps_action_json_example_bw.png -------------------------------------------------------------------------------- /src/pages/getting-started/images/AddAPIConsole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/getting-started/images/AddAPIConsole.png -------------------------------------------------------------------------------- /src/pages/getting-started/images/AddAnotherAPI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/getting-started/images/AddAnotherAPI.png -------------------------------------------------------------------------------- /src/pages/getting-started/images/LandingPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/getting-started/images/LandingPage.png -------------------------------------------------------------------------------- /src/pages/getting-started/images/TestCredential.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/getting-started/images/TestCredential.png -------------------------------------------------------------------------------- /src/pages/getting-started/images/AccessTokenCurlCmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/getting-started/images/AccessTokenCurlCmd.png -------------------------------------------------------------------------------- /src/pages/getting-started/images/AddAPIConsoleLRFF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/getting-started/images/AddAPIConsoleLRFF.png -------------------------------------------------------------------------------- /src/pages/getting-started/images/AddAPIConsolePSFF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/getting-started/images/AddAPIConsolePSFF.png -------------------------------------------------------------------------------- /src/pages/getting-started/images/AddAPIConsoleRBFF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/getting-started/images/AddAPIConsoleRBFF.png -------------------------------------------------------------------------------- /src/pages/getting-started/images/CreateCredential.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/getting-started/images/CreateCredential.png -------------------------------------------------------------------------------- /src/pages/getting-started/images/HelloworldCurlCmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/getting-started/images/HelloworldCurlCmd.png -------------------------------------------------------------------------------- /src/pages/getting-started/images/SelectAPIConsole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/getting-started/images/SelectAPIConsole.png -------------------------------------------------------------------------------- /sample_files/ic_customized_workflow/result_with_path.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/sample_files/ic_customized_workflow/result_with_path.jpg -------------------------------------------------------------------------------- /src/pages/getting-started/images/GenerateTokenWizard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/getting-started/images/GenerateTokenWizard.png -------------------------------------------------------------------------------- /src/pages/getting-started/images/WelcomePhotoshopAPI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/getting-started/images/WelcomePhotoshopAPI.png -------------------------------------------------------------------------------- /src/pages/getting-started/images/AccessTokenCurlConsole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/getting-started/images/AccessTokenCurlConsole.png -------------------------------------------------------------------------------- /src/pages/getting-started/images/CreateNewProjectConsole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/getting-started/images/CreateNewProjectConsole.png -------------------------------------------------------------------------------- /src/pages/getting-started/images/ServicePrincipalConsole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/getting-started/images/ServicePrincipalConsole.png -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | © Copyright 2015-2020 Adobe. All rights reserved. 2 | 3 | Adobe holds the copyright for all the files found in this repository. 4 | 5 | See the LICENSE file for licensing information. -------------------------------------------------------------------------------- /.github/super-linter.env: -------------------------------------------------------------------------------- 1 | IGNORE_GITIGNORED_FILES=true 2 | VALIDATE_GITLEAKS=true 3 | VALIDATE_MARKDOWN=true 4 | MARKDOWN_CONFIG_FILE=.markdownlint.yml 5 | VALIDATE_YAML=true 6 | VALIDATE_JSON=true 7 | -------------------------------------------------------------------------------- /src/pages/getting-started/images/GenerateAccessTokenFromConsole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/HEAD/src/pages/getting-started/images/GenerateAccessTokenFromConsole.png -------------------------------------------------------------------------------- /sample-code/webhook-sample-app/README.md: -------------------------------------------------------------------------------- 1 | # Install Node.js packages 2 | ```bash 3 | npm install http express body-parser 4 | ``` 5 | # Usage 6 | Now, run the app: 7 | 8 | ```bash 9 | node app.js 10 | ``` 11 | -------------------------------------------------------------------------------- /src/pages/release-notes/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Release Notes 3 | description: Page for Release Notes 4 | contributors: 5 | - https://github.com/khound 6 | --- 7 | 8 | ## Release Notes 9 | 10 | More details coming soon ! 11 | -------------------------------------------------------------------------------- /src/pages/api/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Photoshop API Reference 3 | description: This is the OpenAPI page of Adobe Photoshop Service 4 | openAPISpec: https://raw.githubusercontent.com/AdobeDocs/cis-photoshop-api-docs/main/static/swagger.json 5 | ----- 6 | -------------------------------------------------------------------------------- /sample-code/storage-app/googledrive/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "follow-redirect-url": "^2.0.1", 4 | "fs": "^0.0.1-security", 5 | "googleapis": "^118.0.0", 6 | "path": "^0.12.7", 7 | "request": "^2.88.2" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/pages/support/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Support 3 | description: Page for Support 4 | contributors: 5 | - https://github.com/khound 6 | --- 7 | 8 | ## Support Channel 9 | 10 | Please reach out to psdservices@adobe.com or submit a ticket here https://psd-services.zendesk.com/hc/en-us/requests/new for support or feedback. 11 | -------------------------------------------------------------------------------- /sample-code/s3-smart-object-replacement/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "s3-smart-object-replacement", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "aws-sdk": "^2.1095.0", 14 | "request": "^2.88.2" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /sample-code/storage-app/googledrive/service-account.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "service_account", 3 | "project_id": "YOUR PROJECT ID", 4 | "private_key_id": "YOUR PRIVATE KEY", 5 | "private_key": "YOUR KEY", 6 | "client_id": "YOUR CLIENT ID", 7 | "auth_uri": "https://accounts.google.com/o/oauth2/auth", 8 | "token_uri": "https://oauth2.googleapis.com/token", 9 | "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", 10 | "client_x509_cert_url": "YOUR CLIENT CERT URL", 11 | "universe_domain": "googleapis.com" 12 | } 13 | -------------------------------------------------------------------------------- /static/acr/post_auto_tone.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema":"http://json-schema.org/draft-07/schema#", 3 | "$id":"post_auto_tone.schema.json", 4 | "title":"post_auto_tone", 5 | "description":"Initiates an asynchronous job to run auto tone", 6 | "type":"object", 7 | "required":[ 8 | "inputs", 9 | "outputs" 10 | ], 11 | "properties":{ 12 | "inputs":{ 13 | "$ref":"inputs.schema.json#/definitions/inputs" 14 | }, 15 | "outputs":{ 16 | "$ref":"outputs.schema.json#/definitions/outputs" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /sample-code/service-principal-sample-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "service-principal-sample-node", 3 | "version": "1.0.1", 4 | "description": "service-principal node example", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node ./index.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "", 11 | "license": "MIT", 12 | "dependencies": { 13 | "aws-sdk": "^2.329.0", 14 | "jsonwebtoken": "~5.4", 15 | "request": "^2.34.0", 16 | "request-promise": "^4.2.2", 17 | "uuid": "^3.3.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /sample-code/azure-blob-text-edit/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "azure-blob-text-edit", 3 | "version": "1.0.0", 4 | "description": "The following code demostrates how to use Photoshop Text API", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@azure/storage-blob": "^12.14.0", 14 | "request": "^2.88.2" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # Enable version updates for npm 4 | - package-ecosystem: "npm" 5 | # Look for `package.json` and `lock` files in the `root` directory 6 | directory: "/" 7 | # Check the npm registry for updates every day (weekdays) 8 | schedule: 9 | interval: "daily" 10 | allow: 11 | - dependency-name: "@adobe/gatsby-theme-aio" 12 | versioning-strategy: increase 13 | open-pull-requests-limit: 25 14 | labels: 15 | - "dependencies" 16 | ignore: 17 | # Ignore updates to package 18 | - dependency-name: "gatsby" 19 | -------------------------------------------------------------------------------- /sample-code/webhook-sample-app/app.js: -------------------------------------------------------------------------------- 1 | const HTTP = require('http'); 2 | const express = require('express'); 3 | const bodyParser = require('body-parser'); 4 | 5 | let app = express(); 6 | app.use(bodyParser.json({ limit: '10mb' })); 7 | 8 | app.get('/', function(req, res) { 9 | res.end(req.query.challenge); 10 | }); 11 | 12 | app.post('/', function(req, res) { 13 | console.log(JSON.stringify(req.body, null, 2)); 14 | res.end(); 15 | }); 16 | 17 | let startServer = function() { 18 | HTTP.createServer(app).listen(8888); 19 | console.log( { "events-server": "started" }); 20 | } 21 | 22 | startServer(); 23 | -------------------------------------------------------------------------------- /static/PITS/preferences.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema":"http://json-schema.org/draft-07/schema#", 3 | "$id":"preferences.schema.json", 4 | "title":"preferences object", 5 | "description":"preferences settings in photoshop", 6 | "definitions":{ 7 | "preferences": { 8 | "type": "object", 9 | "properties": { 10 | "resizeImageDuringPlace": { 11 | "type": "boolean", 12 | "description": "resize image during place" 13 | }, 14 | "locale": { 15 | "type": "string", 16 | "description": "Locale string such as en_US, fr_FR, de_DE, ja_JP" 17 | } 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /static/PITS/post_social_media_rendition_action.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "post_social_media_rendition_action.schema.json", 4 | "title": "post_social_media_rendition_action_json", 5 | "description": "Initiates an asynchronous job to play Social Media Rendition Actions JSON", 6 | "type": "object", 7 | "required": [ 8 | "inputs", 9 | "outputs" 10 | ], 11 | "properties": { 12 | "inputs": { 13 | "$ref": "file_input.schema.json#/definitions/input_objects_max_2" 14 | }, 15 | "outputs": { 16 | "$ref": "file_output_pegasus.schema.json#/definitions/output_objects" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # OS and IDE generated files # 3 | ############################## 4 | .DS_Store 5 | .vscode 6 | .history 7 | .idea 8 | .editorconfig 9 | 10 | # npm yarn 11 | node_modules 12 | package.lock 13 | yarn-error.log 14 | .pnp.* 15 | .yarn/* 16 | 17 | # keep in repo 18 | !.gitignore 19 | !.yarn.lock 20 | !.yarnrc.yml 21 | !.yarn/patches 22 | !.yarn/plugins 23 | !.yarn/releases 24 | !.yarn/sdks 25 | !.yarn/versions 26 | 27 | # gatsby files 28 | .env 29 | .cache 30 | public 31 | 32 | # cypress 33 | cypress/videos 34 | cypress/screenshots 35 | 36 | # lerna 37 | lerna-debug.log 38 | 39 | # local actions 40 | .actrc 41 | .secrets 42 | local-test.yml 43 | 44 | # yalc 45 | .yalc 46 | yalc.lock -------------------------------------------------------------------------------- /sample-code/storage-app/aws-s3/presignedURLs.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import requests 3 | import json 4 | 5 | client_id = '' 6 | token = '' 7 | 8 | region = '' 9 | bucket = '' 10 | src_key = 'path/to/your/image.jpg' 11 | dest_key = 'path/to/where/you/want/your/output.jpg' 12 | 13 | 14 | def get_presigned_url(bucket, key, operation, expires_in, region): 15 | s3 = boto3.client('s3', region_name=region) 16 | url = s3.generate_presigned_url(operation, Params={'Bucket': bucket, 'Key': key}, ExpiresIn=expires_in) 17 | return url 18 | 19 | input_scr_url = get_presigned_url(bucket, src_key, 'get_object', 3600, region) 20 | output_dest_url = get_presigned_url(bucket, dest_key, 'put_object', 3600, region) 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ### Expected Behaviour 5 | 6 | ### Actual Behaviour 7 | 8 | ### Reproduce Scenario (including but not limited to) 9 | 10 | #### Steps to Reproduce 11 | 12 | #### Platform and Version 13 | 14 | #### Sample Code that illustrates the problem 15 | 16 | #### Logs taken while reproducing problem 17 | -------------------------------------------------------------------------------- /static/PITS/post_rendition_create.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema":"http://json-schema.org/draft-07/schema#", 3 | "$id":"post_rendition_create.schema.json", 4 | "title":"post_rendition_create_operations", 5 | "description":"Initiates an asynchronous job to generate renditions from a PSD file", 6 | "type": "object", 7 | "required":["inputs","outputs"], 8 | "properties": { 9 | "inputs": { 10 | "$ref":"file_input.schema.json#/definitions/input_objects_max_1", 11 | "description":"An object describing an input file. Currently supported filetypes include:`jpeg`, `png`, `psd`, `tiff`. Current support is for files less than 1000MB." 12 | }, 13 | "outputs": { 14 | "$ref":"file_output.schema.json#/definitions/output_objects" 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /sample-code/storage-app/azure/presignedURLs.py: -------------------------------------------------------------------------------- 1 | # need to pip install azure-storage-blob 2 | 3 | from datetime import datetime, timedelta 4 | from azure.storage.blob import BlobServiceClient, generate_account_sas, ResourceTypes, AccountSasPermissions 5 | 6 | storage_account_name = "" 7 | account_access_key = "" 8 | storage_container_name="" 9 | blob_path="" 10 | 11 | sas_token = generate_account_sas( 12 | account_name=storage_account_name, 13 | account_key=account_access_key, 14 | resource_types=ResourceTypes(object=True), 15 | permission=AccountSasPermissions(read=True), 16 | expiry=datetime.utcnow() + timedelta(hours=1) 17 | ) 18 | 19 | the_sas_url = f"https://{storage_account_name}.blob.core.windows.net/{storage_container_name}/{blob_path}?{sas_token}" 20 | print(the_sas_url) 21 | -------------------------------------------------------------------------------- /static/PITS/post_document_operations.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "post_document_operations.schema.json", 4 | "title": "post_document_operations", 5 | "description": "Initiates an asynchronous job to apply edits to a psd and return a new psd and/or renditions", 6 | "type": "object", 7 | "required": [ 8 | "inputs", 9 | "options", 10 | "outputs" 11 | ], 12 | "properties": { 13 | "inputs": { 14 | "$ref": "file_input.schema.json#/definitions/input_objects_max_1" 15 | }, 16 | "options": { 17 | "description": "User can add/update any layer/document properties using options.", 18 | "$ref": "layer_options.schema.json#/definitions/options" 19 | }, 20 | "outputs": { 21 | "$ref": "file_output.schema.json#/definitions/output_objects" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /static/PITS/post_artboard_create.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "post_artboard_create.schema.json", 4 | "title": "post_artboard_create", 5 | "description": "Initiates an asynchronous job to export a list of input PSDs as artboards, to a new psd.", 6 | "type": "object", 7 | "required": [ 8 | "options", 9 | "outputs" 10 | ], 11 | "properties": { 12 | "options": { 13 | "type": "object", 14 | "required": [ 15 | "artboard" 16 | ], 17 | "properties": { 18 | "artboard": { 19 | "$ref": "file_input.schema.json#/definitions/artboard_objects", 20 | "description": "Contains an array of input objects" 21 | } 22 | } 23 | }, 24 | "outputs": { 25 | "$ref": "file_output.schema.json#/definitions/output_objects" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /static/acr/api_response_success_schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "api_response.schema.json", 4 | "title": "api_response", 5 | "description": "Provides API response", 6 | "type": "object", 7 | "properties": { 8 | "_links": { 9 | "type": "object", 10 | "description": "_links hrefs the client can use to get status of the asynchronous job.", 11 | "properties":{ 12 | "self": { 13 | "type": "object", 14 | "properties": { 15 | "href": { 16 | "type": "string", 17 | "format": "string", 18 | "description": "The link that client can use to get status of the asynchronous job", 19 | "example": "https://image.adobe.io/lrService/status/<:jobId>" 20 | } 21 | } 22 | } 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /static/ic/api_response_success_schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "api_response.schema.json", 4 | "title": "api_response", 5 | "description": "Provides API response", 6 | "type": "object", 7 | "properties": { 8 | "_links": { 9 | "type": "object", 10 | "description": "_links hrefs the client can use to get status of the asynchronous job.", 11 | "properties":{ 12 | "self": { 13 | "type": "object", 14 | "properties": { 15 | "href": { 16 | "type": "string", 17 | "format": "string", 18 | "description": "The link that client can use to get status of the asynchronous job", 19 | "example": "https://image.adobe.io/sensei/status/<:jobId>" 20 | } 21 | } 22 | } 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /static/PITS/api_response_success_schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "api_response.schema.json", 4 | "title": "api_response", 5 | "description": "Provides API response", 6 | "type": "object", 7 | "properties": { 8 | "_links": { 9 | "type": "object", 10 | "description": "_links hrefs the client can use to get status of the asynchronous job.", 11 | "properties":{ 12 | "self": { 13 | "type": "object", 14 | "properties": { 15 | "href": { 16 | "type": "string", 17 | "format": "string", 18 | "description": "The link that client can use to get status of the asynchronous job", 19 | "example": "https://image.adobe.io/psdService/status/<:jobId>" 20 | } 21 | } 22 | } 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /sample-code/storage-app/azure/presignedURLs.js: -------------------------------------------------------------------------------- 1 | //Need to npm install @azure/storage-blob 2 | var storage = require("@azure/storage-blob") 3 | const accountname =""; 4 | const key = ""; 5 | const cerds = new storage.StorageSharedKeyCredential(accountname,key); 6 | const blobServiceClient = new storage.BlobServiceClient(`https://${accountname}.blob.core.windows.net`,cerds); 7 | const containerName="test"; 8 | const client =blobServiceClient.getContainerClient(containerName) 9 | const blobName="help.txt"; 10 | const blobClient = client.getBlobClient(blobName); 11 | 12 | const blobSAS = storage.generateBlobSASQueryParameters({ 13 | containerName, 14 | blobName, 15 | permissions: storage.BlobSASPermissions.parse("racwd"), 16 | startsOn: new Date(), 17 | expiresOn: new Date(new Date().valueOf() + 86400) 18 | }, 19 | cerds 20 | ).toString(); 21 | 22 | const sasUrl= blobClient.url+"?"+blobSAS; 23 | console.log(sasUrl); 24 | -------------------------------------------------------------------------------- /static/acr/post_presets.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema":"http://json-schema.org/draft-07/schema#", 3 | "$id":"post_presets.schema.json", 4 | "title":"post_presets", 5 | "description":"Initiates an asynchronous job to apply a preset on an image", 6 | "type":"object", 7 | "required":[ 8 | "inputs", 9 | "outputs" 10 | ], 11 | "properties":{ 12 | "inputs":{ 13 | "type": "object", 14 | "minProperties": 2, 15 | "description": "The input assets for your call", 16 | "required": [ 17 | "source", 18 | "presets" 19 | ], 20 | "properties":{ 21 | "source": { 22 | "$ref":"inputs.schema.json#/definitions/inputs" 23 | }, 24 | "presets": { 25 | "type":"array", 26 | "minItems":1, 27 | "items":{ 28 | "$ref":"inputs.schema.json#/definitions/inputs" 29 | } 30 | } 31 | } 32 | }, 33 | "outputs":{ 34 | "$ref":"outputs.schema.json#/definitions/outputs" 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /static/acr/post_xmp_to_preset.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema":"http://json-schema.org/draft-07/schema#", 3 | "$id":"post_xmp_to_preset.schema.json", 4 | "title":"post_xmp_to_preset", 5 | "description":"Initiates an asynchronous job to apply xmp data to an image", 6 | "type":"object", 7 | "required":[ 8 | "inputs", 9 | "options" 10 | ], 11 | "properties":{ 12 | "inputs":{ 13 | "type": "object", 14 | "minProperties": 1, 15 | "description": "The input assets for your call", 16 | "required": [ 17 | "source" 18 | ], 19 | "properties":{ 20 | "source": { 21 | "$ref":"inputs.schema.json#/definitions/inputs" 22 | } 23 | } 24 | }, 25 | "options":{ 26 | "type":"object", 27 | "minProperties":1, 28 | "required":[ 29 | "xmp" 30 | ], 31 | "properties":{ 32 | "xmp":{ 33 | "type":"string", 34 | "description": "The XMP to apply." 35 | } 36 | }, 37 | "additionalProperties": false 38 | } 39 | }, 40 | "additionalProperties": false 41 | } 42 | -------------------------------------------------------------------------------- /static/PITS/post_document_manifest.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "post_document_manifest.schema.json", 4 | "title": "post_document_manifest", 5 | "description": "Initiates an asynchronous job to extract and return a psd file's layer information", 6 | "type": "object", 7 | "required": ["inputs"], 8 | "properties": { 9 | "inputs": { 10 | "$ref": "file_input.schema.json#/definitions/input_objects_max_1" 11 | }, 12 | "options": { 13 | "type": "object", 14 | "minProperties": 1, 15 | "properties": { 16 | "thumbnails": { 17 | "type": "object", 18 | "description": "Include presigned GET URLs to small preview thumbnails for any renderable layer.", 19 | "minProperties": 1, 20 | "anyOf": [{ 21 | "properties": { 22 | "type": { 23 | "description": "Desired thumbnail format", 24 | "enum": ["image/jpeg", "image/png", "image/tiff"], 25 | "type": "string" 26 | } 27 | } 28 | }] 29 | } 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Deployment 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | env: 7 | description: "Deploy to (dev|prod|dev prod)" 8 | required: true 9 | default: "dev" 10 | clean: 11 | description: "Clean cache" 12 | required: true 13 | type: boolean 14 | default: false 15 | excludeSubfolder: 16 | description: "Exclude a subfolder from deletion" 17 | required: false 18 | default: "" 19 | index-mode: 20 | description: 'Type of indexing. "index" to push to Algolia, "console" for dry run.' 21 | required: true 22 | default: "index" 23 | type: choice 24 | options: 25 | - console 26 | - index 27 | jobs: 28 | deployment: 29 | name: Deployment 30 | uses: AdobeDocs/adp-devsite-workflow/.github/workflows/gatsby-deploy.yml@main 31 | secrets: inherit 32 | with: 33 | env: ${{ inputs.env }} 34 | clean: ${{ inputs.clean }} 35 | excludeSubfolder: ${{ inputs.excludeSubfolder }} 36 | index-mode: ${{ inputs.index-mode }} 37 | NODE_OPTIONS: "--max-old-space-size=8192" 38 | -------------------------------------------------------------------------------- /static/api_response_402_error_schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "api_response_402.schema.json", 4 | "title": "api_response_402", 5 | "description": "Provides API response", 6 | "type": "object", 7 | "properties": { 8 | "title": { 9 | "type": "string", 10 | "format": "string", 11 | "description": "A short, human-readable summary of the problem", 12 | "example": "Trial Limit Exceeded Error" 13 | }, 14 | "type": { 15 | "type": "string", 16 | "format": "string", 17 | "description": "A machine-readable error type", 18 | "example": "TrialLimitExceededError" 19 | }, 20 | "code": { 21 | "type": "string", 22 | "format": "string", 23 | "description": "A machine-readable error code", 24 | "example": 402 25 | }, 26 | "details": { 27 | "type": "string", 28 | "description": "Further descriptions of the exact error where details is substituted for a specific issue.", 29 | "example" : "You have exceeded the limit for the free trial. To upgrade to a paid account please contact your Adobe Account Manager." 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /sample-code/s3-smart-object-replacement/README.md: -------------------------------------------------------------------------------- 1 | # s3-smart-object-replacement 2 | The following code demostrates how to use Photoshop SmartObject Replacement API 3 | 4 | # Instructions 5 | * Open app.js 6 | * fill in the following information 7 | ```node 8 | // FILL OUT INFORMATION ABOUT YOUR ADOBE CREDENTIALS 9 | // VISIT https://developer.adobe.com/console/projects to obtain the following information 10 | const imsConfig = { 11 | clientId: "YOUR_ADOBE_CLIENT_ID", 12 | clientSecret: "YOUR_ADOBE_CLIENT_SECRET" 13 | }; 14 | 15 | // FILL OUT INFORMATION ABOUT YOUR AZURE BLOB STORAGE 16 | const s3BucketName = "YOUR_BUCKET_NAME"; 17 | const awsRegion = "YOUR_BUCKET_REGION" 18 | const s3InputPath = "PATH/TO/input.psd" 19 | const s3ReplacementImagePath = "PATH/TO/REPLACEMENT/image.png" 20 | const s3OutputPath = "PATH/TO/WHERE/YOU/WANT/THE/output.jpg"; 21 | 22 | // FILL OUT INFORMATION ABOUT THE PSD AND TEXTLAYER 23 | const smartObjectLayerName = "NAME_OF_THE_SMARTOBJECT_LAYER"; 24 | ``` 25 | * Run the script 26 | ```bash 27 | npm install 28 | node app.js 29 | ``` 30 | NOTE: This script should work with node.js >= 14 31 | -------------------------------------------------------------------------------- /static/PITS/bounds.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "bounds.schema.json", 4 | "title": "a bounds obect", 5 | "description": "The bounds of the layer. Only applicable for the following layer types: ['layer','textLayer','layerSection','smartObject','contentLayer']", 6 | "definitions": { 7 | "bounds": { 8 | "type": "object", 9 | "minProperties": 1, 10 | "description": "The bounds of the layer. Any of `height`, `left`, `top`, `width` is required", 11 | "anyOf": [{ 12 | "properties": { 13 | "height": { 14 | "type": "number", 15 | "description": "in pixels", 16 | "minimum": 4.00, 17 | "maximum": 32000.00 18 | }, 19 | "left": { 20 | "type": "integer", 21 | "description": "in pixels" 22 | }, 23 | "top": { 24 | "type": "integer", 25 | "description": "in pixels" 26 | }, 27 | "width": { 28 | "type": "number", 29 | "description": "in pixels", 30 | "minimum": 4.00, 31 | "maximum": 32000.00 32 | } 33 | } 34 | }] 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /sample-code/storage-app/aws-s3/presignedURLs.js: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | # install aws-sdk 3 | npm install aws-sdk 4 | # executescript 5 | REGION= BUCKET= OBJECT_KEY= OPERATION= node presignedURLs.js 6 | # example of GET pre-signed url 7 | REGION=us-east-1 BUCKET=john-bucket OBJECT_KEY=some/path/to/image.psd OPERATION=getObject node presignedURLs.js 8 | # example of PUT pre-signed url 9 | REGION=us-east-1 BUCKET=john-bucket OBJECT_KEY=some/path/to/where/you/want/the/ouptut.jpg OPERATION=putObject node presignedURLs.js 10 | ************************************************/ 11 | var AWS = require('aws-sdk') 12 | var bucket = process.env.BUCKET 13 | var object_key = process.env.OBJECT_KEY 14 | var operation = process.env.OPERATION || 'putObject' 15 | var region = process.env.REGION 16 | AWS.config.update({"region": region}); 17 | 18 | 19 | let params = {Bucket: bucket, Key: object_key, Expires: 3600 * 24}; 20 | let s3 = new AWS.S3({apiVersion: '2006-03-01', signatureVersion: 'v4'}); 21 | s3.getSignedUrl(operation, params, function (err, url) { 22 | if(err){ 23 | console.log(err) 24 | }else{ 25 | console.log(url) 26 | } 27 | }); 28 | -------------------------------------------------------------------------------- /sample-code/azure-blob-text-edit/README.md: -------------------------------------------------------------------------------- 1 | # azure-blob-text-edit 2 | The following code demostrates how to use Photoshop Text API 3 | 4 | # Instructions 5 | * Open app.js 6 | * fill in the following information 7 | ```node 8 | // FILL OUT INFORMATION ABOUT YOUR ADOBE CREDENTIALS 9 | // VISIT https://developer.adobe.com/console/projects to obtain the following information 10 | const imsConfig = { 11 | clientId: "YOUR_ADOBE_CLIENT_ID", 12 | clientSecret: "YOUR_ADOBE_CLIENT_SECRET" 13 | }; 14 | 15 | // FILL OUT INFORMATION ABOUT YOUR AZURE BLOB STORAGE 16 | const azureStorageAccountName = "YOUR_AZURE_STORAGE_ACCOUNT_NAME"; 17 | const azureAccountAccessKey = "YOUR_AZURE_ACCOUNT_ACCESS_KEY" 18 | const azureInputPath = "PATH/TO/INPUT/FILE/IN/YOUR/AZURE/account.psd"; 19 | const azureOutputPath = "PATH/TO/WHERE/YOUR/WANT/THE/output.jpg"; 20 | const azureContainerName= "YOUR_AZURE_COTAINER_NAME"; 21 | 22 | // FILL OUT INFORMATION ABOUT THE PSD AND TEXTLAYER 23 | const textLayerName = "NAME_OF_THE_LAYER"; 24 | const textLayerContent = "YOUR_CONTENT"; 25 | ``` 26 | * Run the script 27 | ```bash 28 | npm install 29 | node app.js 30 | ``` 31 | NOTE: This script should work with node.js >= 10 32 | -------------------------------------------------------------------------------- /static/acr/post_mask.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema":"http://json-schema.org/draft-07/schema#", 3 | "$id":"post_mask.schema.json", 4 | "title":"post_mask", 5 | "description":"Initiates an asynchronous job to generate a mask for an image", 6 | "type":"object", 7 | "required":[ 8 | "options" 9 | ], 10 | "properties":{ 11 | "options":{ 12 | "type":"object", 13 | "minProperties":1, 14 | "required":[ 15 | "maskType", 16 | "version" 17 | ], 18 | "properties":{ 19 | "referenceJobId":{ 20 | "type":"string", 21 | "description": "If present, it indicates that the input asset to this job would be from the reference job ID specified." 22 | }, 23 | "maskType":{ 24 | "type":"string", 25 | "description": "The type of mask to generate.", 26 | "enum": [ 27 | "selectSubject", 28 | "selectObject", 29 | "selectSky", 30 | "selectSkin" 31 | ] 32 | }, 33 | "version":{ 34 | "type":"string", 35 | "description": "The version of Camera RAW to use while generating the mask." 36 | } 37 | }, 38 | "additionalProperties": false 39 | } 40 | }, 41 | "additionalProperties": false 42 | } 43 | -------------------------------------------------------------------------------- /static/PITS/post_product_crop_action_json.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "post_product_crop_action.schema.json", 4 | "title": "post_product_crop_action_json", 5 | "description": "Initiates an asynchronous job to play Product Crop Action JSON", 6 | "type": "object", 7 | "required": [ 8 | "inputs", 9 | "options", 10 | "outputs" 11 | ], 12 | "properties": { 13 | "inputs": { 14 | "$ref": "file_input.schema.json#/definitions/input_objects_max_1" 15 | }, 16 | "options": { 17 | "type": "object", 18 | "required": ["unit","width","height"], 19 | "properties": { 20 | "unit": { 21 | "type": "string", 22 | "description": "Unit for width and height", 23 | "enum": [ 24 | "Pixels", 25 | "Percent" 26 | ] 27 | }, 28 | "width": { 29 | "type": "number", 30 | "description": "The width to be added as padding." 31 | }, 32 | "height": { 33 | "type": "number", 34 | "description": "The height to be added as padding." 35 | } 36 | } 37 | }, 38 | "outputs": { 39 | "$ref": "file_output_pegasus.schema.json#/definitions/output_objects" 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /static/acr/post_xmp.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema":"http://json-schema.org/draft-07/schema#", 3 | "$id":"post_xmp.schema.json", 4 | "title":"post_xmp", 5 | "description":"Initiates an asynchronous job to apply xmp data to an image", 6 | "type":"object", 7 | "required":[ 8 | "inputs", 9 | "outputs", 10 | "options" 11 | ], 12 | "properties":{ 13 | "inputs":{ 14 | "type": "object", 15 | "minProperties": 1, 16 | "description": "The input assets for your call", 17 | "required": [ 18 | "source" 19 | ], 20 | "properties":{ 21 | "source": { 22 | "$ref":"inputs.schema.json#/definitions/inputs" 23 | } 24 | } 25 | }, 26 | "outputs":{ 27 | "$ref":"outputs.schema.json#/definitions/outputs" 28 | }, 29 | "options":{ 30 | "type":"object", 31 | "minProperties":1, 32 | "required":[ 33 | "xmp" 34 | ], 35 | "properties":{ 36 | "xmp":{ 37 | "type":"string", 38 | "description": "The XMP to apply." 39 | }, 40 | "orientation":{ 41 | "type":"number", 42 | "description": "The combination of flip and/or rotate to apply", 43 | "minimum": 1, 44 | "maximum": 8 45 | } 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /static/PITS/post_action_json_create.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "post_action_json_create.schema.json", 4 | "title": "post_action_json_create", 5 | "description": "Initiates an asynchronous job to convert an .atn file to actionJSON", 6 | "definitions": { 7 | "action_object": { 8 | "type": "object", 9 | "minProperties": 1, 10 | "properties": { 11 | "actionName": { 12 | "description": "If you only want to execute a particular action, you may specify whcih action to convert from the ActionSet", 13 | "type": "string" 14 | } 15 | } 16 | } 17 | }, 18 | "type": "object", 19 | "required": ["inputs"], 20 | "properties": { 21 | "inputs": { 22 | "$ref": "file_input.schema.json#/definitions/input_objects_max_1" 23 | }, 24 | "options": { 25 | "type": "object", 26 | "description": "This block is needed only if you want to specify whcih action to convert from the ActionSet ", 27 | "required": ["actions"], 28 | "properties": { 29 | "actions": { 30 | "type": "array", 31 | "minItems": 1, 32 | "maxItems": 1, 33 | "items": { 34 | "$ref": "#/definitions/action_object" 35 | } 36 | } 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /static/acr/post_auto_straighten.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "post_auto_straighten.schema.json", 4 | "title": "post_auto_straighten", 5 | "description": "Initiates an asynchronous job to run auto straighten", 6 | "type": "object", 7 | "required": [ 8 | "inputs", 9 | "outputs" 10 | ], 11 | "properties": { 12 | "inputs": { 13 | "$ref": "inputs.schema.json#/definitions/inputs" 14 | }, 15 | "options": { 16 | "type": "object", 17 | "required": [ 18 | "uprightMode" 19 | ], 20 | "properties": { 21 | "uprightMode": { 22 | "type": "string", 23 | "enum": [ 24 | "auto", 25 | "full", 26 | "level", 27 | "vertical" 28 | ], 29 | "description": "The upright mode to use. If you have the options block, then this is a required field. If options block is not specified, then the appropriate upright mode will automatically be selected." 30 | }, 31 | "constrainCrop": { 32 | "type": "boolean", 33 | "description": "If the straightened image should be constrain cropped, to remove all blank edges around an image.", 34 | "default" : true 35 | } 36 | } 37 | }, 38 | "outputs": { 39 | "$ref": "outputs.schema.json#/definitions/outputs" 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /static/api_response_403_error_schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "api_response_403.schema.json", 4 | "title": "api_response_403", 5 | "description": "Provides API response", 6 | "type": "object", 7 | "properties": { 8 | "title": { 9 | "type": "string", 10 | "format": "string", 11 | "description": "A short, human-readable summary of the problem", 12 | "example": "Unauthorized" 13 | }, 14 | "type": { 15 | "type": "string", 16 | "format": "string", 17 | "description": "A machine-readable error type", 18 | "example": "InvalidAuthTokenError" 19 | }, 20 | "code": { 21 | "type": "string", 22 | "format": "string", 23 | "description": "A machine-readable error code", 24 | "example": 403 25 | }, 26 | "details": { 27 | "type": "object", 28 | "description": "Further descriptions of the exact error where details is substituted for a specific issue.", 29 | "properties": { 30 | "name": { 31 | "type": "string", 32 | "description": "Name for the detailed error.", 33 | "example": "" 34 | }, 35 | "reason": { 36 | "type": "string", 37 | "description": "Details of error reason.", 38 | "example": "Unable to access the input href" 39 | } 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /static/api_response_409_error_schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "api_response_409.schema.json", 4 | "title": "api_response_409", 5 | "description": "Provides API response", 6 | "type": "object", 7 | "properties": { 8 | "title": { 9 | "type": "string", 10 | "format": "string", 11 | "description": "A short, human-readable summary of the problem", 12 | "example": "Unable to upload asset" 13 | }, 14 | "type": { 15 | "type": "string", 16 | "format": "string", 17 | "description": "A machine-readable error type", 18 | "example": "FileOverwriteError" 19 | }, 20 | "code": { 21 | "type": "string", 22 | "format": "string", 23 | "description": "A machine-readable error code", 24 | "example": 409 25 | }, 26 | "details": { 27 | "type": "object", 28 | "description": "Further descriptions of the exact error where details is substituted for a specific issue.", 29 | "properties": { 30 | "name": { 31 | "type": "string", 32 | "description": "Name for the detailed error.", 33 | "example": "Asset Upload Error" 34 | }, 35 | "reason": { 36 | "type": "string", 37 | "description": "Details of error reason.", 38 | "example": "File exists and overwrite is diabled" 39 | } 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /static/api_response_404_error_schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "api_response_404.schema.json", 4 | "title": "api_response_404", 5 | "description": "Provides API response", 6 | "type": "object", 7 | "properties": { 8 | "title": { 9 | "type": "string", 10 | "format": "string", 11 | "description": "A short, human-readable summary of the problem", 12 | "example": "Requested resource was not found" 13 | }, 14 | "type": { 15 | "type": "string", 16 | "format": "string", 17 | "description": "A machine-readable error type", 18 | "example": "ResourceNotFound" 19 | }, 20 | "code": { 21 | "type": "integer", 22 | "format": "int", 23 | "description": "A machine-readable error code", 24 | "example": 404 25 | }, 26 | "details": { 27 | "type": "object", 28 | "description": "Further descriptions of the exact error where details is substituted for a specific issue.", 29 | "properties": { 30 | "name": { 31 | "type": "string", 32 | "description": "Name for the detailed error.", 33 | "example": "" 34 | }, 35 | "reason": { 36 | "type": "string", 37 | "description": "Details of error reason.", 38 | "example": "Unable to access the input href" 39 | } 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /static/api_response_400_error_schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "api_response_400.schema.json", 4 | "title": "api_response_400", 5 | "description": "Provides API response", 6 | "type": "object", 7 | "properties": { 8 | "title": { 9 | "type": "string", 10 | "format": "string", 11 | "description": "A short, human-readable summary of the problem", 12 | "example": "InputValidationError" 13 | }, 14 | "type": { 15 | "type": "string", 16 | "format": "string", 17 | "description": "A machine-readable error type", 18 | "example": "InputValidationError" 19 | }, 20 | "code": { 21 | "type": "string", 22 | "format": "string", 23 | "description": "A machine-readable error code", 24 | "example": 400 25 | }, 26 | "details": { 27 | "type": "object", 28 | "description": "Further descriptions of the exact error where details is substituted for a specific issue.", 29 | "properties": { 30 | "allowedValues": { 31 | "type": "string", 32 | "description": "Name for the detailed error.", 33 | "example": "adobe, external, dropbox, azure" 34 | }, 35 | "reason": { 36 | "type": "string", 37 | "description": "Details of error reason.", 38 | "example": "should be equal to one of the allowed values." 39 | } 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "cis-photoshop-api-docs", 4 | "version": "1.0.0", 5 | "license": "Apache-2.0", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/AdobeDocs/dev-site-product-template" 9 | }, 10 | "author": { 11 | "name": "Sudipta Khound", 12 | "url": "https://github.com/khound" 13 | }, 14 | "dependencies": { 15 | "@adobe/gatsby-theme-aio": "^4.14.4", 16 | "gatsby": "4.22.0", 17 | "react": "17.0.2", 18 | "react-dom": "17.0.2" 19 | }, 20 | "scripts": { 21 | "start": "gatsby build && gatsby serve", 22 | "start:prefix": "gatsby build --prefix-paths && gatsby serve --prefix-paths", 23 | "dev": "gatsby develop", 24 | "dev:https": "gatsby develop --https --host localhost.corp.adobe.com --port 9000", 25 | "build": "gatsby build", 26 | "build:incremental": "GATSBY_EXPERIMENTAL_PAGE_BUILD_ON_DATA_CHANGES=true gatsby build --log-pages", 27 | "serve": "gatsby serve", 28 | "clean": "gatsby clean", 29 | "test:links": "remark src/pages --quiet --frail", 30 | "lint": "docker run --rm -e RUN_LOCAL=true --env-file '.github/super-linter.env' -v \"$PWD\":/tmp/lint github/super-linter:slim-v4.10.1" 31 | }, 32 | "remarkConfig": { 33 | "plugins": [ 34 | "remark-validate-links" 35 | ] 36 | }, 37 | "packageManager": "yarn@3.2.1", 38 | "devDependencies": { 39 | "remark-cli": "^11.0.0", 40 | "remark-validate-links": "^12.1.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /static/api_response_410_error_schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "api_response_410.schema.json", 4 | "title": "api_response_410", 5 | "description": "Provides API response", 6 | "type": "object", 7 | "properties": { 8 | "title": { 9 | "type": "string", 10 | "format": "string", 11 | "description": "A short, human-readable summary of the problem", 12 | "example": "Asset Link Invalid" 13 | }, 14 | "type": { 15 | "type": "string", 16 | "format": "string", 17 | "description": "A machine-readable error type", 18 | "example": "FileLinkInvalidError" 19 | }, 20 | "code": { 21 | "type": "string", 22 | "format": "string", 23 | "description": "A machine-readable error code", 24 | "example": 410 25 | }, 26 | "details": { 27 | "type": "object", 28 | "description": "Further descriptions of the exact error where details is substituted for a specific issue.", 29 | "properties": { 30 | "name": { 31 | "type": "string", 32 | "description": "Name for the detailed error.", 33 | "example": "Asset Download Error" 34 | }, 35 | "reason": { 36 | "type": "string", 37 | "description": "Details of error reason.", 38 | "example": "Unable to download the input href. The link is either invalid or has expired." 39 | } 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /static/PITS/post_layer_brightness_contrast.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema":"http://json-schema.org/draft-07/schema#", 3 | "$id":"post_layer_brightness_contrast.schema.json", 4 | "title":"post_layer_brightness_contrast", 5 | "description":"Initiates an asynchronous job to edit existing brightness and contrast settings in PSD files", 6 | "type": "object", 7 | "required":["inputs","options","outputs"], 8 | "properties": { 9 | "inputs": { 10 | "$ref":"file_input.schema.json#/definitions/input_objects_max_1" 11 | }, 12 | "options": { 13 | "type":"object", 14 | "required":["layers"], 15 | "properties": { 16 | "layers" :{ 17 | "type":"array", 18 | "minItems":1, 19 | "items":{ 20 | "type":"object", 21 | "required":[ "id","attributes" ], 22 | "properties":{ 23 | "id": { 24 | "$ref":"layers.schema.json#/definitions/id" 25 | }, 26 | "attributes": { 27 | "type":"object", 28 | "properties": { 29 | "brightnessContrast": { 30 | "$ref":"adjustments.schema.json#/definitions/brightnessContrast" 31 | } 32 | } 33 | } 34 | } 35 | } 36 | } 37 | } 38 | }, 39 | "outputs": { 40 | "$ref":"file_output.schema.json#/definitions/output_objects" 41 | }, 42 | "jobId": { 43 | "type": "string" 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /sample-code/storage-app/googledrive/presignedURLs.js: -------------------------------------------------------------------------------- 1 | /* 2 | Google Drive API: 3 | Demonstration to:create public URL of a file. 4 | 5 | Instructions to run 6 | npm install 7 | node presignedURLs.js 8 | 9 | service-account.json is a generated file by google drive autorizarion. We have attached a sample example 10 | Photoshoshop APIs don't support redirect . So you need to use redirected url (line 42) 11 | */ 12 | const { google } = require('googleapis'); 13 | const fs = require('fs'); 14 | const followRedirect = require('follow-redirect-url'); 15 | 16 | const SCOPES = ['https://www.googleapis.com/auth/drive']; 17 | const SERVICE_ACCOUNT_FILE = './service-account.json'; 18 | 19 | async function getFileUrl(fileId) { 20 | const auth = new google.auth.GoogleAuth({ 21 | keyFile: SERVICE_ACCOUNT_FILE, 22 | scopes: SCOPES, 23 | }); 24 | 25 | const drive = google.drive({ version: 'v3', auth }); 26 | 27 | try { 28 | const res = await drive.files.get({ fileId, fields: 'webContentLink' }); 29 | return res.data.webContentLink; 30 | } catch (error) { 31 | console.error('An error occurred:', error.message); 32 | return null; 33 | } 34 | } 35 | 36 | async function main() { 37 | const fileId = 'your-file-id-goes-here'; 38 | const fileUrl = await getFileUrl(fileId); 39 | 40 | if (fileUrl) { 41 | const redirectlink = await followRedirect.startFollowing(fileUrl) 42 | console.log('The URL for the file is:', redirectlink[1].url); 43 | } else { 44 | console.log('Failed to retrieve the file URL.'); 45 | } 46 | } 47 | 48 | main(); 49 | -------------------------------------------------------------------------------- /.github/linters/.yaml-lint.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ########################################### 3 | # These are the rules used for # 4 | # linting all the yaml files in the stack # 5 | # NOTE: # 6 | # You can disable line with: # 7 | # # yamllint disable-line # 8 | ########################################### 9 | rules: 10 | braces: 11 | level: warning 12 | min-spaces-inside: 0 13 | max-spaces-inside: 0 14 | min-spaces-inside-empty: 1 15 | max-spaces-inside-empty: 5 16 | brackets: 17 | level: warning 18 | min-spaces-inside: 0 19 | max-spaces-inside: 0 20 | min-spaces-inside-empty: 1 21 | max-spaces-inside-empty: 5 22 | colons: 23 | level: warning 24 | max-spaces-before: 0 25 | max-spaces-after: 1 26 | commas: 27 | level: warning 28 | max-spaces-before: 0 29 | min-spaces-after: 1 30 | max-spaces-after: 1 31 | comments: disable 32 | comments-indentation: disable 33 | document-end: disable 34 | document-start: 35 | level: warning 36 | present: true 37 | empty-lines: 38 | level: warning 39 | max: 2 40 | max-start: 0 41 | max-end: 0 42 | hyphens: 43 | level: warning 44 | max-spaces-after: 1 45 | indentation: 46 | level: warning 47 | spaces: consistent 48 | indent-sequences: true 49 | check-multi-line-strings: false 50 | key-duplicates: enable 51 | line-length: 52 | level: warning 53 | max: 100 54 | allow-non-breakable-words: true 55 | allow-non-breakable-inline-mappings: true 56 | new-line-at-end-of-file: disable 57 | new-lines: 58 | type: unix 59 | trailing-spaces: disable 60 | -------------------------------------------------------------------------------- /.github/linters/.markdownlint.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ########################### 3 | ########################### 4 | ## Markdown Linter rules ## 5 | ########################### 6 | ########################### 7 | 8 | # Linter rules doc: 9 | # - https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md 10 | # 11 | # Note: 12 | # To comment out a single error: 13 | # 14 | # any violations you want 15 | # 16 | # 17 | 18 | # Default state for all rules 19 | default: false 20 | 21 | ################# 22 | # Rules by tags # 23 | ################# 24 | blanks-around-fences: true # Fenced code blocks should be surrounded by blank lines 25 | blanks-around-headings: true # Headings should be surrounded by blank lines 26 | blanks-around-lists: true # Lists should be surrounded by blank lines 27 | code-block-style: 28 | style: "fenced" 29 | code-fence-style: 30 | style: "backtick" 31 | emphasis-style: 32 | style: "consistent" 33 | fenced-code-language: true # Fenced code blocks should have a language specified 34 | heading-start-left: true # Headings must start at the beginning of the line 35 | heading-style: 36 | style: "atx" 37 | hr-style: true # Horizontal rule style 38 | list-indent: true # Inconsistent indentation for list items at the same level 39 | no-empty-links: true 40 | no-missing-space-atx: true # No space after hash on atx style heading 41 | no-multiple-blanks: true # Multiple consecutive blank lines 42 | no-reversed-links: true 43 | no-space-in-code: true 44 | no-space-in-emphasis: true 45 | no-space-in-links: true 46 | no-trailing-spaces: true 47 | single-trailing-newline: true # Files should end with a single newline character 48 | strong-style: 49 | style: "consistent" 50 | ul-style: 51 | style: "consistent" 52 | -------------------------------------------------------------------------------- /.github/workflows/github-pages.yml: -------------------------------------------------------------------------------- 1 | name: Github Pages 2 | on: 3 | push: 4 | branches: [main] 5 | jobs: 6 | build-and-deploy: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout 10 | uses: actions/checkout@v2.3.1 # If you're using actions/checkout@v2 you must set persist-credentials to false in most cases for the deployment to work correctly. 11 | with: 12 | persist-credentials: false 13 | - name: NPM Install 14 | uses: bahmutov/npm-install@v1 15 | - name: Build 16 | run: | 17 | npm run build 18 | env: 19 | PREFIX_PATHS: true # equivalent to --prefix-paths flag for 'gatsby build' 20 | PATH_PREFIX: ${{ github.event.repository.name }} 21 | ADOBE_LAUNCH_SRC: ${{ secrets.AIO_ADOBE_LAUNCH_SRC }} 22 | ADOBE_LAUNCH_SRC_INCLUDE_IN_DEVELOPMENT: ${{ secrets.ADOBE_LAUNCH_SRC_INCLUDE_IN_DEVELOPMENT }} 23 | REPO_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 24 | REPO_OWNER: ${{ github.event.repository.owner.login }} 25 | REPO_NAME: ${{ github.event.repository.name }} 26 | REPO_BRANCH: ${{ steps.vars.outputs.BRANCH_SHORT_REF }} 27 | GOOGLE_OAUTH_CLIENT_ID: ${{ secrets.GOOGLE_OAUTH_CLIENT_ID }} 28 | GOOGLE_OAUTH_CLIENT_SECRET: ${{ secrets.GOOGLE_OAUTH_CLIENT_SECRET }} 29 | GOOGLE_DOCS_TOKEN: ${{ secrets.GOOGLE_DOCS_TOKEN }} 30 | GOOGLE_DOCS_FOLDER_ID: ${{ secrets.GOOGLE_DOCS_FOLDER_ID }} 31 | - name: Deploy to GH Pages 32 | uses: JamesIves/github-pages-deploy-action@3.7.1 33 | with: 34 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 35 | BRANCH: gh-pages # The branch the action should deploy to. 36 | FOLDER: public # The folder the action should deploy. 37 | CLEAN: true # Automatically remove deleted files from the deploy branch -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Description 4 | 5 | 6 | 7 | ## Related Issue 8 | 9 | 10 | 11 | 12 | 13 | 14 | ## Motivation and Context 15 | 16 | 17 | 18 | ## How Has This Been Tested? 19 | 20 | 21 | 22 | 23 | 24 | ## Screenshots (if appropriate): 25 | 26 | ## Types of changes 27 | 28 | 29 | 30 | - [ ] Bug fix (non-breaking change which fixes an issue) 31 | - [ ] New feature (non-breaking change which adds functionality) 32 | - [ ] Breaking change (fix or feature that would cause existing functionality to change) 33 | 34 | ## Checklist: 35 | 36 | 37 | 38 | 39 | - [ ] I have signed the [Adobe Open Source CLA](https://opensource.adobe.com/cla.html). 40 | - [ ] My code follows the code style of this project. 41 | - [ ] My change requires a change to the documentation. 42 | - [ ] I have updated the documentation accordingly. 43 | - [ ] I have read the **CONTRIBUTING** document. 44 | - [ ] I have added tests to cover my changes. 45 | - [ ] All new and existing tests passed. 46 | -------------------------------------------------------------------------------- /src/pages/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Overview - Adobe Photoshop API 3 | description: This is the overview page of Adobe Photoshop API 4 | Keywords:: 5 | - Photoshop API documentation 6 | - Remove background API documentation 7 | - Smart Object API documentation 8 | - Create Mask API documentation 9 | - 10 | contributors: 11 | - https://github.com/khound 12 | - https://github.com/archyposada 13 | --- 14 | 15 | 16 | 17 | ![Hero image](./hero.png) 18 | 19 | # Adobe Photoshop and Lightroom API 20 | 21 | Unlock the potential of Photoshop, Lightroom, and cutting edge Sensei services through an easy-to-use RESTful API. 22 | 23 | ## Welcome to Photoshop and Lightroom API! 24 | 25 | The Photoshop and Lightroom API allows you to efficiently produce and scale content by automating repetitive, mundane tasks that would otherwise take time from a valuable creative or budget with outsourcing to an agency. Our API extends an organization’s capabilities to do more with the tools they already have at their fingertips. 26 | 27 | - Create internal applications to help scale your content supply chain or build web applications to help unlock creativity anywhere. 28 | 29 | - Generate thousands of variations and renditions within minutes instead of days. 30 | 31 | ## Overview 32 | 33 | The Photoshop and Lightroom API will allow you to make both layer and document level edits to Photoshop PSD and other image files via a wide range of image editing features that span Photoshop, Lightroom, and Sensei services. 34 | 35 | The Photoshop and Lightroom API is designed with REST-like principles and uses standard HTTP response codes, verbs and authentication that returns JSON-encoded responses. The [examples](../photoshop-api-docs/code-sample/) you see are written in cURL but we support the language of your choice. 36 | 37 | The [Getting Started](../photoshop-api-docs/getting-started/) page will walk you through how to use our API. 38 | 39 |
40 |
41 |
42 |
43 | -------------------------------------------------------------------------------- /.github/scripts/get-path-prefix.js: -------------------------------------------------------------------------------- 1 | // This script retrieves the pathPrefix from the gatsby-config.js file. 2 | // It serves as an example for how to set up external javascript functions 3 | // outside workflow .yml files when they get too big or complex to keep them inline. 4 | 5 | // Documentation for the actions/github-script: 6 | // https://github.com/actions/github-script#run-a-separate-file 7 | 8 | module.exports = async ({ core }) => { 9 | const { pathPrefix } = await require('../../gatsby-config.js'); 10 | 11 | if (!pathPrefix) { 12 | core.setFailed( 13 | `The pathPrefix in the site's gatsby-config.js file is missing. 14 | 15 | To fix this, open your gatsby-config.js file, and add it to the config object: 16 | 17 | module.exports = { 18 | pathPrefix: "/commerce/frontend-core/", 19 | ... 20 | }` 21 | ); 22 | } else if (pathPrefix === '/') { 23 | core.setFailed( 24 | `The pathPrefix in the site's gatsby-config.js file is set to "/". This is not allowed. 25 | 26 | To fix this, change the pathPrefix to include a name that starts and ends with "/": 27 | 28 | pathPrefix: "/commerce/frontend - core/" 29 | 30 | This name identifies the site within the developer.adobe.com domain: 31 | https://developer.adobe.com/document-services/. 32 | ` 33 | ); 34 | } else { 35 | if (!pathPrefix.startsWith('/') || !pathPrefix.endsWith('/')) { 36 | core.setFailed( 37 | `The pathPrefix in the site's gatsby-config.js file does not start or end with "/". 38 | 39 | To fix this, change the pathPrefix to include a name that starts and ends with "/". 40 | For example: "/document-services/" or "/commerce/cloud-tools/". 41 | 42 | This is required by convention because of the way we construct site URLs. 43 | For example: https://developer.adobe.com + /document-services/ + path/to/files/. 44 | ` 45 | ); 46 | } 47 | } 48 | core.setOutput('path_prefix', pathPrefix); 49 | }; 50 | -------------------------------------------------------------------------------- /static/PITS/post_photoshop_actions.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "post_photoshop_actions.schema.json", 4 | "title": "post_photoshop_actions", 5 | "description": "Initiates an asynchronous job to play Photoshop Actions", 6 | "type": "object", 7 | "required": ["inputs", "options", "outputs"], 8 | "properties": { 9 | "inputs": { 10 | "$ref": "file_input.schema.json#/definitions/input_objects_max_1" 11 | }, 12 | "options": { 13 | "type": "object", 14 | "minProperties": 1, 15 | "allOf": [{ 16 | "properties": { 17 | "actions": { 18 | "$ref": "file_input.schema.json#/definitions/input_objects_action", 19 | "description": "An action object which tells the API where to download the action file" 20 | }, 21 | "fonts": { 22 | "$ref": "file_input.schema.json#/definitions/input_objects", 23 | "description": "An array of font objects you wish to use when executing the action." 24 | }, 25 | "patterns": { 26 | "$ref": "file_input.schema.json#/definitions/input_objects", 27 | "description": "Array of pattern objects (We currently only support one input object) An array of pattern objects you wish photoshopActions to use when playing an action that requires a custom pattern." 28 | }, 29 | "brushes": { 30 | "$ref": "file_input.schema.json#/definitions/input_objects", 31 | "description": "An array of brush objects you wish to use when executing the action." 32 | } 33 | }, 34 | "anyOf": [{ 35 | "required": [ 36 | "actions" 37 | ] 38 | }, 39 | { 40 | "required": [ 41 | "uxp" 42 | ] 43 | } 44 | ] 45 | }] 46 | }, 47 | "outputs": { 48 | "$ref": "file_output_pegasus.schema.json#/definitions/output_objects" 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /sample-code/storage-app/aws-s3/example.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | from botocore.config import Config 3 | import requests 4 | import json 5 | 6 | client_id = '' 7 | token = '' 8 | 9 | region = '' 10 | bucket = '' 11 | src_key = 'path/to/your/image.jpg' 12 | dest_key = 'path/to/where/you/want/your/output.jpg' 13 | 14 | #path to your service api. This example is showing autoTone API 15 | autotone_url = 'https://image.adobe.io/lrService/autoTone' 16 | 17 | 18 | def get_presigned_url(bucket, key, operation, expires_in, region): 19 | s3 = boto3.client('s3', config=Config(signature_version='s3v4'), region_name=region) 20 | url = s3.generate_presigned_url(operation, Params={'Bucket': bucket, 'Key': key}, ExpiresIn=expires_in) 21 | return url 22 | 23 | def invoke_autotone(url, headers, payload): 24 | resp = requests.post(url, json=payload, headers=headers) 25 | return resp 26 | 27 | def get_autotone_status(url, headers): 28 | resp = requests.get(url, headers=headers) 29 | return resp 30 | 31 | def poll_status(resp, headers): 32 | tmp = json.loads(resp.text) 33 | url = tmp['_links']['self']['href'] 34 | print(url) 35 | while True: 36 | resp_status = get_autotone_status(url, headers) 37 | tmp_status = json.loads(resp_status.text) 38 | status = tmp_status['outputs'][0]['status'] 39 | if status == 'failed' or status == 'succeeded': 40 | print(status) 41 | return resp 42 | else: 43 | print(status) 44 | 45 | 46 | input_scr_url = get_presigned_url(bucket, src_key, 'get_object', 3600, region) 47 | output_dest_url = get_presigned_url(bucket, dest_key, 'put_object', 3600, region) 48 | 49 | headers = { "Authorization": "Bearer {token}", "x-api-key" : client_id } 50 | payload = { 51 | "inputs":{ 52 | "href": input_scr_url, 53 | "storage": "external" 54 | }, 55 | "outputs": [ 56 | { 57 | "href": output_dest_url, 58 | "storage": "external", 59 | "type": "image/jpeg" 60 | } 61 | ] 62 | } 63 | 64 | resp = invoke_autotone(autotone_url, headers, payload) 65 | status = poll_status(resp, headers) 66 | 67 | print(resp) 68 | @khound 69 | -------------------------------------------------------------------------------- /static/PITS/layer_options.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "layer_options.schema.json", 4 | "title": "an option obect", 5 | "description": "Layer Options for add or edit", 6 | "definitions": { 7 | "options": { 8 | "type": "object", 9 | "minProperties": 1, 10 | "description": "Layer Options for add or edit", 11 | "anyOf": [ 12 | { 13 | "properties": { 14 | "layers": { 15 | "$ref": "layers.schema.json#/definitions/layer_objects" 16 | }, 17 | "document": { 18 | "$ref": "document.schema.json#/definitions/document", 19 | "description": "Set of document level edits. Document level edits will always be applied AFTER layer level edits have been performed. One of `canvasSize`, `imageSize` or `trim` is required" 20 | }, 21 | "globalFont": { 22 | "type": "string", 23 | "description": "The full postscript name of the font to be used as the global default for the document. This font will be used for any text layer which has a missing font and no other font has been specifically provided for that layer. If this font itself is missing, the option specified for manageMissingFonts from above will take effect." 24 | }, 25 | "fonts": { 26 | "$ref": "file_input.schema.json#/definitions/input_objects", 27 | "description": "Array of custom fonts needed in this document" 28 | }, 29 | "manageMissingFonts": { 30 | "enum": [ 31 | "fail", 32 | "useDefault" 33 | ], 34 | "default": "useDefault", 35 | "description": "Action to take if there are one or more missing fonts in the document. `fail` - The job will not succeed and the status will be set to `failed`, with the details of the error provided in the `details` section in the status.`useDefault` - The job will succeed, however, by default all the missing fonts will be replaced with this font: ArialMT" 36 | } 37 | } 38 | } 39 | ] 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thanks for choosing to contribute! 4 | 5 | The following are a set of guidelines to follow when contributing to this project. 6 | 7 | ## Code Of Conduct 8 | 9 | This project adheres to the Adobe [code of conduct](../CODE_OF_CONDUCT.md). By participating, 10 | you are expected to uphold this code. Please report unacceptable behavior to 11 | [Grp-opensourceoffice@adobe.com](mailto:Grp-opensourceoffice@adobe.com). 12 | 13 | ## Have A Question? 14 | 15 | Start by filing an issue. The existing committers on this project work to reach 16 | consensus around project direction and issue solutions within issue threads 17 | (when appropriate). 18 | 19 | ## Contributor License Agreement 20 | 21 | All third-party contributions to this project must be accompanied by a signed contributor 22 | license agreement. This gives Adobe permission to redistribute your contributions 23 | as part of the project. [Sign our CLA](https://opensource.adobe.com/cla.html). You 24 | only need to submit an Adobe CLA one time, so if you have submitted one previously, 25 | you are good to go! 26 | 27 | ## Code Reviews 28 | 29 | All submissions should come in the form of pull requests and need to be reviewed 30 | by project committers. Read [GitHub's pull request documentation](https://help.github.com/articles/about-pull-requests/) 31 | for more information on sending pull requests. 32 | 33 | Lastly, please follow the [pull request template](PULL_REQUEST_TEMPLATE.md) when 34 | submitting a pull request! 35 | 36 | ## From Contributor To Committer 37 | 38 | We love contributions from our community! If you'd like to go a step beyond contributor 39 | and become a committer with full write access and a say in the project, you must 40 | be invited to the project. The existing committers employ an internal nomination 41 | process that must reach lazy consensus (silence is approval) before invitations 42 | are issued. If you feel you are qualified and want to get more deeply involved, 43 | feel free to reach out to existing committers to have a conversation about that. 44 | 45 | ## Security Issues 46 | 47 | Security issues shouldn't be reported on this issue tracker. Instead, [file an issue to our security experts](https://helpx.adobe.com/security/alertus.html). 48 | -------------------------------------------------------------------------------- /gatsby-config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Adobe. All rights reserved. 3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. You may obtain a copy 5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | * 7 | * Unless required by applicable law or agreed to in writing, software distributed under 8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | * OF ANY KIND, either express or implied. See the License for the specific language 10 | * governing permissions and limitations under the License. 11 | */ 12 | 13 | module.exports = { 14 | siteMetadata: { 15 | pages: [ 16 | { 17 | title: 'Photoshop API Overview', 18 | path: '/' 19 | }, 20 | { 21 | title: 'Getting Started', 22 | path: '/getting-started/' 23 | }, 24 | { 25 | title: 'General Workflow', 26 | path: '/general-workflow/' 27 | }, 28 | { 29 | title: 'Features', 30 | path: '/features/' 31 | }, 32 | { 33 | title: 'Code Samples', 34 | path: '/code-sample/' 35 | }, 36 | { 37 | title: 'API Documentation', 38 | path: '/api/' 39 | }, 40 | { 41 | title: 'Support', 42 | menu:[{ 43 | title: 'Submit a ticket', 44 | path: 'https://psd-services.zendesk.com/hc/en-us/requests/new' 45 | }, { 46 | title: 'Community Forums', 47 | path: 'https://community.adobe.com/t5/photoshop-developers/ct-p/ct-photoshop-developers?page=1&sort=latest_replies&lang=all&tabid=all&topics=label-psautomationapi' 48 | }] 49 | } 50 | ], 51 | subPages: [ 52 | { 53 | title: 'Getting Started', 54 | path: '/getting-started/' 55 | }, 56 | { 57 | title: 'General Workflow', 58 | path: '/general-workflow/' 59 | }, 60 | { 61 | title: 'Features', 62 | path: '/features/' 63 | }, 64 | { 65 | title: 'Code Samples', 66 | path: '/code-sample/' 67 | } 68 | ] 69 | }, 70 | plugins: [`@adobe/gatsby-theme-aio`], 71 | pathPrefix: process.env.PATH_PREFIX || '/photoshop/photoshop-api-docs/' 72 | }; 73 | -------------------------------------------------------------------------------- /static/PITS/iccProfile.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "iccProfile.schema.json", 4 | "title": "an iccProfile obect", 5 | "description": "An object describing the icc profile to convert to.", 6 | "definitions": { 7 | "iccProfile": { 8 | "type": "object", 9 | "description": "An object describing the icc profile to convert to.", 10 | "minProperties": 1, 11 | "properties": { 12 | "imageMode": { 13 | "type": "string", 14 | "description": "The image mode .Allowed values for iccProfile file `grayscale`, `rgb`, `cmyk` . Allowed values for iccProfile Name `rgb`, `grayscale`. " 15 | }, 16 | "profileName": { 17 | "type": "string", 18 | "description": "The name of the color profile", 19 | "enum": [ 20 | "Adobe RGB (1998)", 21 | "Apple RGB", 22 | "ColorMatch RGB", 23 | "sRGB IEC61966-2.1", 24 | "Dot Gain 10%", 25 | "Dot Gain 15%", 26 | "Dot Gain 20%", 27 | "Dot Gain 25%", 28 | "Dot Gain 30%", 29 | "Gray Gamma 1.8", 30 | "Gray Gamma 2.2" 31 | ] 32 | }, 33 | "input": { 34 | "type": "object", 35 | "description": "An object describing the icc profile. ", 36 | "minProperties": 1, 37 | "properties": { 38 | "href": { 39 | "description": "Either a presignedGETURL OR a Creative Cloud assets path for storage='adobe'.", 40 | "type": "string", 41 | "minLength": 1, 42 | "example": "presignedURL" 43 | }, 44 | "storage": { 45 | "description": "Asset stored on an external service (like AWS S3, Azure, Dropbox) or Adobe's Creative Cloud files. If you are using presigned url for dropbox or azure, use `storage=\"dropbox\"` or `storage=\"azure\"` else it is `storage=\"external\"`", 46 | "type": "string", 47 | "enum": [ 48 | "external", 49 | "azure", 50 | "dropbox", 51 | "adobe", 52 | "cclib" 53 | ], 54 | "default": "external" 55 | } 56 | } 57 | } 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /static/acr/inputs.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "inputs.schema.json", 4 | "title": "a file input obect", 5 | "description": "An input object", 6 | "definitions": { 7 | "href": { 8 | "description": "Either a presignedURL for storage='external' OR Creative Cloud assets path for storage='adobe' ", 9 | "type": "string", 10 | "minLength": 1 11 | }, 12 | "storage": { 13 | "description": "Storage platforms supported.", 14 | "type": "string", 15 | "enum": [ 16 | "external", 17 | "lightroom", 18 | "dropbox", 19 | "azure", 20 | "adobe" 21 | ], 22 | "default": "external" 23 | }, 24 | "inputs": { 25 | "type": "object", 26 | "minProperties": 1, 27 | "description": "An input file to add or edit", 28 | "required": [ 29 | "href", 30 | "storage" 31 | ], 32 | "properties": { 33 | "storage": { 34 | "$ref": "#/definitions/storage" 35 | }, 36 | "href": { 37 | "$ref": "#/definitions/href" 38 | } 39 | }, 40 | "if": { 41 | "properties": { 42 | "storage": { 43 | "pattern": "(^azure|external|dropbox$)", 44 | "description": "Asset stored on an external service (like AWS S3, Azure, Dropbox etc.). If you are using presigned url for dropbox or azure, use `storage=\"dropbox\"` or `storage=\"azure\"` else it is `storage=\"external\"`" 45 | } 46 | } 47 | }, 48 | "then": { 49 | "properties": { 50 | "href": { 51 | "format": "uri", 52 | "pattern": "^https://", 53 | "description": "Any public url or a presignedURL for the asset input" 54 | } 55 | } 56 | }, 57 | "else": { 58 | "properties": { 59 | "href": { 60 | "pattern": "^/?(temp|cloud-content|assets|pubs)/.+", 61 | "description": "A string representing the path to the input file stored on Adobe's cloud.
Not available for the integrations created with JWT authentication or Service Principle." 62 | }, 63 | "storage": { 64 | "description" : "Asset stored on Adobe's cloud.
Not available for the integrations created with JWT authentication or Service Principle." 65 | } 66 | } 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /static/acr/get_status.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "get_status_success.schema.json", 4 | "title": "get_status", 5 | "description": "Returns the status of a job.", 6 | "type": "object", 7 | "properties": { 8 | "jobId": { 9 | "type": "string", 10 | "description": "The job's id requested", 11 | "example": "f54e0fcb-260b-47c3-b520-de0d17dc2b67" 12 | }, 13 | "created": { 14 | "type": "string", 15 | "format": "YYYY-DD-MMThh:mm:ss.mmmmmZ", 16 | "description": "Created timestamp of the job." 17 | }, 18 | "modified": { 19 | "type": "string", 20 | "format": "YYYY-DD-MMThh:mm:ss.mmmmmZ", 21 | "description": "Modified timestamp of the job." 22 | }, 23 | "outputs": { 24 | "type": "array", 25 | "minItems": 1, 26 | "items" : { 27 | "properties": { 28 | "input": { 29 | "type": "string", 30 | "description": "The original input href.", 31 | "example": "presigned_GET_URL" 32 | }, 33 | "status": { 34 | "type": "string", 35 | "description": "The job status", 36 | "enum": [ 37 | "pending", 38 | "running", 39 | "succeeded", 40 | "failed" 41 | ], 42 | "example": "string" 43 | }, 44 | "details": { 45 | "type": "string", 46 | "description": "Description of the exact error that is reported by the requested job. Will appear in the response only if there is an error." 47 | }, 48 | "_links": { 49 | "type": "object", 50 | "properties": { 51 | "self": { 52 | "type": "object", 53 | "properties": { 54 | "href": { 55 | "$ref": "inputs.schema.json#/definitions/href" 56 | }, 57 | "storage": { 58 | "$ref": "inputs.schema.json#/definitions/storage" 59 | } 60 | } 61 | } 62 | } 63 | } 64 | } 65 | } 66 | }, 67 | "_links": { 68 | "type": "object", 69 | "properties": { 70 | "self": { 71 | "type": "object", 72 | "properties": { 73 | "href": { 74 | "type": "string", 75 | "description": "Link that client can use to track status.", 76 | "example": "https://image.adobe.io/lrService/status/f54e0fcb-260b-47c3-b520-de0d17dc2b67" 77 | } 78 | } 79 | } 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /static/PITS/get_status.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "get_status_success.schema.json", 4 | "title": "get_status", 5 | "description": "Returns the status of a job.", 6 | "type": "object", 7 | "properties": { 8 | "jobId": { 9 | "type": "string", 10 | "description": "The job's id requested", 11 | "example": "f54e0fcb-260b-47c3-b520-de0d17dc2b67" 12 | }, 13 | "outputs": { 14 | "type": "array", 15 | "minItems": 1, 16 | "items": { 17 | "properties": { 18 | "input": { 19 | "type": "string", 20 | "description": "The original input href.", 21 | "example": "presigned_GET_URL" 22 | }, 23 | "status": { 24 | "type": "string", 25 | "description": "The job status", 26 | "enum": [ 27 | "pending", 28 | "starting", 29 | "running", 30 | "succeeded", 31 | "failed" 32 | ], 33 | "example": "string" 34 | }, 35 | "created": { 36 | "type": "string", 37 | "format": "YYYY-DD-MMThh:mm:ss.mmmmmZ", 38 | "description": "Created timestamp of the job." 39 | }, 40 | "modified": { 41 | "type": "string", 42 | "format": "YYYY-DD-MMThh:mm:ss.mmmmmZ", 43 | "description": "Modified timestamp of the job." 44 | }, 45 | "_links": { 46 | "type": "object", 47 | "properties": { 48 | "renditions": { 49 | "type": "array", 50 | "minItems": 1, 51 | "description": "Array of rendition objects", 52 | "items": { 53 | "properties": { 54 | "href": { 55 | "$ref": "file_input.schema.json#/definitions/href" 56 | }, 57 | "storage": { 58 | "$ref": "file_input.schema.json#/definitions/storage" 59 | }, 60 | "width": { 61 | "$ref": "file_output.schema.json#/definitions/width" 62 | }, 63 | "type": { 64 | "$ref": "file_output.schema.json#/definitions/type" 65 | } 66 | } 67 | } 68 | } 69 | } 70 | } 71 | } 72 | } 73 | }, 74 | "_links": { 75 | "type": "object", 76 | "properties": { 77 | "self": { 78 | "type": "object", 79 | "properties": { 80 | "href": { 81 | "type": "string", 82 | "description": "Link that client can use to track status.", 83 | "example": "https://image.adobe.io/pie/psdService/status/f54e0fcb-260b-47c3-b520-de0d17dc2b67" 84 | } 85 | } 86 | } 87 | } 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /static/PITS/post_smart_object.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "post_smart_object.schema.json", 4 | "title": "post_smart_object", 5 | "description": "Initiates an asynchronous job to replace an embedded smart object and also create one ", 6 | "type": "object", 7 | "required": ["inputs", "options", "outputs"], 8 | "properties": { 9 | "inputs": { 10 | "$ref": "file_input.schema.json#/definitions/input_objects_max_1" 11 | }, 12 | "options": { 13 | "type": "object", 14 | "minProperties": 1, 15 | "description": "User can replace smart object layers using options block ", 16 | "required": ["layers"], 17 | "properties": { 18 | "layers": { 19 | "type": "array", 20 | "minItems": 1, 21 | "items": { 22 | "type": "object", 23 | "allOf": [{ 24 | "properties": { 25 | "name": { 26 | "$ref": "layers.schema.json#/definitions/name" 27 | }, 28 | "id": { 29 | "$ref": "layers.schema.json#/definitions/id" 30 | }, 31 | "locked": { 32 | "$ref": "layers.schema.json#/definitions/locked" 33 | }, 34 | "visible": { 35 | "$ref": "layers.schema.json#/definitions/visible" 36 | }, 37 | "add": { 38 | "$ref": "layers.schema.json#/definitions/add", 39 | "description": "Inidicates you want to add a new layer. You must also indicate where you want to insert the new layer by supplying one of the attributes `insertAbove`, `insertBelow`, `insertInto`,`insertTop` or `insertBottom`. `add` block overwrites default `edit` block." 40 | }, 41 | "input": { 42 | "$ref": "file_input.schema.json#/definitions/input_object", 43 | "description": "An object describing the input file to add or replace for the Embedded Smart Object layer. Edited images are replaced for exact pixel size. Currently supported filetypes includes `png`,`jpeg`,`psd`,`svg`,`ai`,`pdf`." 44 | }, 45 | "bounds": { 46 | "$ref": "bounds.schema.json#/definitions/bounds", 47 | "description": "The bounds of this layer. While replacing a smart object if you provide the same aspect ratio(width / height) as of the actual image as a bound,the embedded SO will not be a distorted image." 48 | } 49 | }, 50 | "anyOf": [{ 51 | "required": [ 52 | "name" 53 | ] 54 | }, 55 | { 56 | "required": [ 57 | "id" 58 | ] 59 | } 60 | ] 61 | }], 62 | "required": [ 63 | "input" 64 | ] 65 | } 66 | } 67 | } 68 | }, 69 | "outputs": { 70 | "$ref": "file_output.schema.json#/definitions/output_objects_smart_object" 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/pages/features/supported-fonts/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Fonts in Photoshop Service 3 | description: Learn about the available fonts in Photoshop Service. 4 | --- 5 | 6 | ## Photoshop API Supported Fonts 7 | 8 | This is a list of all of the currently supported Postscript fonts for Photoshop API's. Additionally the user can use any fonts they are authorized to access via [Adobe Fonts](https://fonts.adobe.com/fonts). (Currently only available for OAuth tokens, service token support is forthcoming...) 9 | 10 | ### Photoshop CC 11 | | | 12 | |---------------------------------- | 13 | | AcuminVariableConcept | 14 | | AdobeArabic-Bold | 15 | | AdobeArabic-BoldItalic | 16 | | AdobeArabic-Italic | 17 | | AdobeArabic-Regular | 18 | | AdobeDevanagari-Bold | 19 | | AdobeDevanagari-BoldItalic | 20 | | AdobeDevanagari-Italic | 21 | | AdobeDevanagari-Regular | 22 | | AdobeFanHeitiStd-Bold | 23 | | AdobeGothicStd-Bold | 24 | | AdobeGurmukhi-Bold | 25 | | AdobeGurmukhi-Regular | 26 | | AdobeHebrew-Bold | 27 | | AdobeHebrew-BoldItalic | 28 | | AdobeHebrew-Italic | 29 | | AdobeHebrew-Regular | 30 | | AdobeHeitiStd-Regular | 31 | | AdobeMingStd-Light | 32 | | AdobeMyungjoStd-Medium | 33 | | AdobePiStd | 34 | | AdobeSongStd-Light | 35 | | AdobeThai-Bold | 36 | | AdobeThai-BoldItalic | 37 | | AdobeThai-Italic | 38 | | AdobeThai-Regular | 39 | | CourierStd | 40 | | CourierStd-Bold | 41 | | CourierStd-BoldOblique | 42 | | CourierStd-Oblique | 43 | | EmojiOneColor | 44 | | KozGoPr6N-Bold | 45 | | KozGoPr6N-Medium | 46 | | KozGoPr6N-Regular | 47 | | KozMinPr6N-Regular | 48 | | MinionPro-Regular | 49 | | MinionVariableConcept-Italic | 50 | | MinionVariableConcept-Roman | 51 | | MyriadArabic-Bold | 52 | | MyriadArabic-BoldIt | 53 | | MyriadArabic-It | 54 | | MyriadArabic-Regular | 55 | | MyriadHebrew-Bold | 56 | | MyriadHebrew-BoldIt | 57 | | MyriadHebrew-It | 58 | | MyriadHebrew-Regular | 59 | | MyriadPro-Bold | 60 | | MyriadPro-BoldIt | 61 | | MyriadPro-It | 62 | | MyriadPro-Regular | 63 | | MyriadVariableConcept-Italic | 64 | | MyriadVariableConcept-Roman | 65 | | NotoSansKhmer-Regular | 66 | | NotoSansLao-Regular | 67 | | NotoSansMyanmar-Regular | 68 | | NotoSansSinhala-Regular | 69 | | SourceCodeVariable-Italic | 70 | | SourceCodeVariable-Roman | 71 | | SourceSansVariable-Italic | 72 | | SourceSansVariable-Roman | 73 | | SourceSerifVariable-Roman | 74 | | TrajanColor-Concept | 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Adobe I/O Documentation Template 2 | 3 | This is a Gatsby site template built with [Adobe I/O Gatsby Theme](https://github.com/adobe/gatsby-theme-aio). 4 | 5 | View the [demo](https://adobedocs.github.io/dev-site-documentation-template/) running on Github Pages. 6 | 7 | ## Where to ask for help 8 | 9 | The slack channel #adobeio-onsite-onboarding is our main point of contact for help. Feel free to join the channel and ask any questions. 10 | 11 | ## How to develop 12 | 13 | For local development 14 | Open a terminal at the root of your local cis-photoshop-api-doc project/site and run the following command: 15 | 16 | Run 17 | ``` 18 | yarn install 19 | yarn dev 20 | ``` 21 | 22 | If you have a M1 mac. You need to install vips before `yarn install`. Run 23 | ``` 24 | brew install vips 25 | ``` 26 | 27 | Make sure to run lint locally before you check-in 28 | ``` 29 | npx @redocly/cli@latest lint static/swagger.json --extends minimal --format json --lint-config=off 30 | ``` 31 | Fix any lint errors before checking-in 32 | 33 | To clean up any cache 34 | 35 | ``` 36 | yarn clean && yarn cache clean && rm -rf node_modules && rm package-lock.json && rm yarn.lock 37 | ``` 38 | If you remove `yarn.lock`, make sure to create an empty `yarn.lock` file at the root of your local cis-photoshop-api-doc project after clean up and run `yarn install` 39 | 40 | 41 | To see the changes reflected locally, point the `swagger.json` to your local 42 | 43 | ``` 44 | Modify src/pages/api/index.md to point openAPISpec to your local swagger.json 45 | openAPISpec: /swagger.json 46 | ``` 47 | 48 | For the documentation developer, please read these sections on how to: 49 | - [Arrange the structure content of your docs](https://github.com/adobe/gatsby-theme-aio#content-structure) 50 | - [Linking to pages](https://github.com/adobe/gatsby-theme-aio#links) 51 | - [Using assets](https://github.com/adobe/gatsby-theme-aio#assets) 52 | - [Setting Global Navigation](https://github.com/adobe/gatsby-theme-aio#global-navigation) 53 | - [Setting Side Navigation](https://github.com/adobe/gatsby-theme-aio#side-navigation) 54 | - [Using content blocks](https://github.com/adobe/gatsby-theme-aio#jsx-blocks) 55 | - [Notes on using Markdown](https://github.com/adobe/gatsby-theme-aio#writing-enhanced-markdown) 56 | 57 | For more in-depth [instructions](https://github.com/adobe/gatsby-theme-aio#getting-started). 58 | 59 | ## How to deploy 60 | 61 | For any team that wishes to deploy to the adobe.io and stage.adobe.io website, they must be in contact with the dev-site team. Teams will be given a path that will follow the pattern `adobe.io/{product}/`. This will allow doc developers to setup their subpaths to look something like: 62 | ``` 63 | adobe.io/{product}/docs 64 | adobe.io/{product}/community 65 | adobe.io/{product}/community/code_of_conduct 66 | adobe.io/{product}/community/contribute 67 | ``` 68 | 69 | ### Launching a deploy 70 | 71 | You can deploy using the GitHub actions deploy workflow see [deploy instructions](https://github.com/adobe/gatsby-theme-aio#deploy-to-azure-storage-static-websites). 72 | 73 | ## How to file an issue (for customers) 74 | For issues, bugs, questions, or feedback please file a ticket by submitting a form at https://psd-services.zendesk.com/hc/en-us/requests/new 75 | -------------------------------------------------------------------------------- /static/PITS/document.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "document.schema.json", 4 | "title": "a document object", 5 | "description": "Document level edits. Right now supports crop and resize.", 6 | "definitions": { 7 | "document": { 8 | "type": "object", 9 | "minProperties": 1, 10 | "description": "Set of document level edits. Document level edits will always be applied AFTER layer level edits have been performed.", 11 | "anyOf": [{ 12 | "properties": { 13 | "imageSize": { 14 | "$ref": "#/definitions/imageSize" 15 | }, 16 | "canvasSize": { 17 | "$ref": "#/definitions/canvasSize" 18 | }, 19 | "trim": { 20 | "$ref": "#/definitions/trim" 21 | } 22 | } 23 | }] 24 | }, 25 | "trim": { 26 | "type": "object", 27 | "minProperties": 1, 28 | "required": ["basedOn"], 29 | "description": "Image trim parameters.", 30 | "properties": { 31 | "basedOn": { 32 | "type": "string", 33 | "description": "what pixels should the trim be based on", 34 | "enum": ["transparentPixels"] 35 | } 36 | } 37 | }, 38 | "imageSize": { 39 | "type": "object", 40 | "minProperties": 1, 41 | "description": "Resize parameters. resizing a PSD always maintains the original aspect ratio by default. If the new width & height values specified in the parameters does not match the original aspect ratio, then the specified height will not be used and the height will be determined automatically.", 42 | "allOf": [{ 43 | "required": ["height"] 44 | }, 45 | { 46 | "required": ["width"] 47 | } 48 | ], 49 | "properties": { 50 | "height": { 51 | "type": "integer", 52 | "description": "in pixels" 53 | }, 54 | "width": { 55 | "type": "integer", 56 | "description": "in pixels" 57 | } 58 | } 59 | }, 60 | "canvasSize": { 61 | "type": "object", 62 | "minProperties": 1, 63 | "description": "Crop parameters", 64 | "required": ["bounds"], 65 | "properties": { 66 | "bounds": { 67 | "type": "object", 68 | "description": "The bounds to crop a document", 69 | "minProperties": 1, 70 | "anyOf": [{ 71 | "properties": { 72 | "top": { 73 | "type": "integer", 74 | "minimum": 0, 75 | "description": "in pixels, y co-ordinate of top left of the document" 76 | }, 77 | "left": { 78 | "type": "integer", 79 | "minimum": 0, 80 | "description": "in pixels, x co-ordinate top left of the document" 81 | }, 82 | "bottom": { 83 | "type": "integer", 84 | "minimum": 0, 85 | "description": "in pixels, y co-ordinate of bottom right of the document" 86 | }, 87 | "right": { 88 | "type": "integer", 89 | "minimum": 0, 90 | "description": "in pixels, x co-ordinate bottom right of the document" 91 | } 92 | } 93 | }] 94 | } 95 | } 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /static/PITS/get_manifest_status.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "get_status_success.schema.json", 4 | "title": "get_status", 5 | "description": "Returns the status of a job.", 6 | "type": "object", 7 | "properties": { 8 | "jobId": { 9 | "type": "string", 10 | "description": "The job's id requested", 11 | "example": "f54e0fcb-260b-47c3-b520-de0d17dc2b67" 12 | }, 13 | "outputs": { 14 | "type": "array", 15 | "minItems": 1, 16 | "items": { 17 | "properties": { 18 | "input": { 19 | "type": "string", 20 | "description": "The original input href.", 21 | "example": "presigned_GET_URL" 22 | }, 23 | "status": { 24 | "type": "string", 25 | "description": "The job status", 26 | "enum": [ 27 | "pending", 28 | "running", 29 | "succeeded", 30 | "failed" 31 | ], 32 | "example": "succeeded" 33 | }, 34 | "created": { 35 | "type": "string", 36 | "format": "YYYY-DD-MMThh:mm:ss.mmmmmZ", 37 | "description": "Created timestamp of the job.", 38 | "example": "2018-01-04T12:57:15.12345Z" 39 | }, 40 | "modified": { 41 | "type": "string", 42 | "format": "YYYY-DD-MMThh:mm:ss.mmmmmZ", 43 | "description": "Modified timestamp of the job.", 44 | "example": "2018-01-04T12:58:36.12345Z" 45 | }, 46 | "document": { 47 | "type": "object", 48 | "properties": { 49 | "name": { 50 | "type": "string", 51 | "description": "Name of the input file", 52 | "example": "wine.psd" 53 | }, 54 | "height": { 55 | "type": "number", 56 | "description": "In pixels", 57 | "example" : 2100 58 | }, 59 | "width": { 60 | "type": "number", 61 | "description": "In pixels", 62 | "example" : 1500 63 | }, 64 | "photoshopBuild": { 65 | "type": "string", 66 | "description": "The name of the application that created the PSD", 67 | "example": "Adobe Photoshop CC 2019 (20180815.cyan.124 2018/08/15: 1186932) (Macintosh)" 68 | }, 69 | "imageMode": { 70 | "type": "string", 71 | "description": "The document's image mode.", 72 | "example" : "rgb" 73 | }, 74 | "bitDepth": { 75 | "type": "number", 76 | "description": "The document's bit/channel depth. Allowed values `bitmap`, `greyscale`, `indexed`, `rgb`, `cmyk`, `hsl`, `hsb`, `multichannel`, `duotone`, `lab`, `xyz`", 77 | "example" : "bitmap" 78 | }, 79 | "iccProfileName": { 80 | "type": "string", 81 | "description": "icc profile", 82 | "example" : "sRGB IEC61966-2.1" 83 | } 84 | } 85 | }, 86 | "layers": { 87 | "$ref": "layers_manifest.schema.json#/definitions/layer_objects" 88 | } 89 | } 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /static/PITS/post_smart_object_v2.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "post_smart_object_v2.schema.json", 4 | "title": "post_smart_object_v2", 5 | "description": "Initiates an asynchronous job to replace an embedded smart object and also create one ", 6 | "type": "object", 7 | "required":["inputs","options","outputs"], 8 | "properties": { 9 | "inputs": { 10 | "$ref":"file_input.schema.json#/definitions/input_objects_max_1" 11 | }, 12 | "options":{ 13 | "type": "object", 14 | "minProperties": 1, 15 | "required": ["layers"], 16 | "properties": { 17 | "preferences":{ 18 | "$ref":"preferences.schema.json#/definitions/preferences" 19 | }, 20 | "layers": { 21 | "type": "array", 22 | "minItems": 1, 23 | "items": { 24 | "oneOf": [ 25 | { 26 | "required": [ 27 | "id" 28 | ] 29 | }, 30 | { 31 | "required": [ 32 | "name" 33 | ] 34 | } 35 | ], 36 | "oneOf": [ 37 | { 38 | "required": [ 39 | "input" 40 | ] 41 | }, 42 | { 43 | "required": [ 44 | "smartObject" 45 | ] 46 | } 47 | ], 48 | "properties": { 49 | "id": { 50 | "type": "integer", 51 | "description": "The id of the layer you want to insert. Use either id OR name." 52 | }, 53 | "name": { 54 | "type": "string", 55 | "description": "The name of the layer you want to insert . Use either id OR name" 56 | }, 57 | "locked": { 58 | "type": "boolean", 59 | "description": "is the layer editable" 60 | }, 61 | "visible": { 62 | "type": "boolean", 63 | "description": "is the layer visible" 64 | }, 65 | "input": { 66 | "$ref":"file_input.schema.json#/definitions/input_object" 67 | }, 68 | "bounds":{ 69 | "$ref":"bounds.schema.json#/definitions/bounds" 70 | }, 71 | "resizeImageDuringPlace": { 72 | "type": "boolean", 73 | "description": "resize image during place" 74 | }, 75 | "transformToCanvas": { 76 | "type": "string", 77 | "description": "method to transform image to canvas", 78 | "default": "fit" 79 | }, 80 | "fillToCanvas": { 81 | "type": "boolean", 82 | "description": "transform image to fill canvas", 83 | "default": false 84 | }, 85 | "smartObject": { 86 | "description": "smartObject layer" 87 | } 88 | } 89 | } 90 | } 91 | }, 92 | "jobId": { 93 | "type": "string" 94 | }, 95 | "outputs": { 96 | "$ref": "file_output_pegasus.schema.json#/definitions/output_objects" 97 | } 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Adobe Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language. 18 | * Being respectful of differing viewpoints and experiences. 19 | * Gracefully accepting constructive criticism. 20 | * Focusing on what is best for the community. 21 | * Showing empathy towards other community members. 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances. 27 | * Trolling, insulting/derogatory comments, and personal or political attacks. 28 | * Public or private harassment. 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission. 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting. 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at Grp-opensourceoffice@adobe.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [https://contributor-covenant.org/version/1/4][version]. 72 | 73 | [homepage]: https://contributor-covenant.org 74 | [version]: https://contributor-covenant.org/version/1/4/ 75 | -------------------------------------------------------------------------------- /static/PITS/file_output_action_json_create.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "file_output_action_json_create.schema.json", 4 | "title": "a file output obect", 5 | "description": "Represents the collective fields needed to indicate an output file, destination and format", 6 | "definitions": { 7 | "output_object": { 8 | "type": "object", 9 | "description": "An object describing the requested file outputs", 10 | "required": [ 11 | "href", 12 | "storage", 13 | "type" 14 | ], 15 | "properties": { 16 | "storage": { 17 | "$ref": "file_input.schema.json#/definitions/storage" 18 | }, 19 | "href": { 20 | "type": "string", 21 | "minLength": 1 22 | }, 23 | "type": { 24 | "description": "desired image format.", 25 | "enum": [ 26 | "application/json" 27 | ], 28 | "type": "string" 29 | }, 30 | "overwrite": { 31 | "description": "if the output file already exists should it be overwritten. Will eventually support eTags", 32 | "type": "boolean", 33 | "default": true 34 | } 35 | }, 36 | "allOf": [ 37 | { 38 | "if": { 39 | "properties": { 40 | "storage": { 41 | "pattern": "(^azure|external|dropbox$)", 42 | "description": "Asset stored on an external service (like AWS S3, Azure, Dropbox). If you are using presigned url for dropbox or azure, use `storage=\"dropbox\"` or `storage=\"azure\"` else it is `storage=\"external\"`" 43 | } 44 | } 45 | }, 46 | "then": { 47 | "properties": { 48 | "href": { 49 | "type": "string", 50 | "pattern": "^https://", 51 | "description": "Any public url or a presignedURL for the asset output" 52 | } 53 | } 54 | }, 55 | "else": { 56 | "if" : { 57 | "properties": { 58 | "storage": { 59 | "pattern": "(^cclib$)" 60 | } 61 | } 62 | }, 63 | "then" : { 64 | "properties": { 65 | "href": { 66 | "pattern": "^/?(api)/.+", 67 | "description": "A string representing the path to the output CC Libraries file.
Not available for the integrations created with JWT authentication or Service Principal." 68 | } 69 | } 70 | }, 71 | "else" : { 72 | "properties": { 73 | "href": { 74 | "pattern": "^/?(temp|cloud-content|assets|pubs)/.+", 75 | "description": "A string representing the path to the output CC Storage file.
Not available for the integrations created with JWT authentication or Service Principal." 76 | } 77 | } 78 | } 79 | } 80 | } 81 | ] 82 | }, 83 | "output_objects": { 84 | "type": "array", 85 | "minItems": 1, 86 | "maxItems": 25, 87 | "description": "An array of hashes describing the output files. Output file format can be `.json` and storage type can be any of `external`, `adobe`, `azure` or `dropbox`. Maximum limit of 25 per request.", 88 | "items": { 89 | "$ref": "#/definitions/output_object" 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /static/PITS/text.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "text.schema.json", 4 | "title": "a text object", 5 | "description": "text layer attributes", 6 | "definitions": { 7 | "text": { 8 | "type": "object", 9 | "description": "Supported text layer attributes.", 10 | "minProperties": 1, 11 | "properties": { 12 | "content": { 13 | "type": "string", 14 | "description": "The text string" 15 | }, 16 | "characterStyles": { 17 | "$ref": "#/definitions/character_styles" 18 | }, 19 | "paragraphStyles": { 20 | "$ref": "#/definitions/paragraph_styles" 21 | } 22 | } 23 | }, 24 | "character_styles": { 25 | "type": "array", 26 | "minItems": 1, 27 | "description": "Array of character_style objects", 28 | "items": { 29 | "$ref": "#/definitions/character_style" 30 | } 31 | }, 32 | "character_style": { 33 | "type": "object", 34 | "description": "character style settings", 35 | "minProperties": 1, 36 | "properties": { 37 | "from": { 38 | "$ref": "#/definitions/from" 39 | }, 40 | "to": { 41 | "$ref": "#/definitions/to" 42 | }, 43 | "fontSize": { 44 | "type": "number", 45 | "description": "The font size, in pixels", 46 | "minimum": 0.04, 47 | "maximum": 5400 48 | }, 49 | "fontName": { 50 | "type": "string", 51 | "description": "The font's postscript name. See `https://github.com/AdobeDocs/photoshop-api-docs/blob/master/SupportedFonts.md` for the list of currently supported fonts" 52 | }, 53 | "fontColor": { 54 | "$ref": "fontColor.schema.json#/definitions/fontColor" 55 | }, 56 | "orientation": { 57 | "type": "string", 58 | "description": "The text's orientation", 59 | "enum": ["horizontal", "vertical"] 60 | } 61 | } 62 | }, 63 | "paragraph_styles": { 64 | "type": "array", 65 | "minItems": 1, 66 | "description": "Array of paragraph_style objects", 67 | "items": { 68 | "$ref": "#/definitions/paragraph_style" 69 | } 70 | }, 71 | "paragraph_style": { 72 | "type": "object", 73 | "description": "Array of paragraph_style object. `alignment` is required.", 74 | "minProperties": 1, 75 | "required": ["alignment"], 76 | "properties": { 77 | "alignment": { 78 | "type": "string", 79 | "description": "The paragraph alignment", 80 | "enum": ["left", "center", "right", "justify", "justifyLeft", "justifyCenter", "justifyRight"] 81 | }, 82 | "from": { 83 | "$ref": "#/definitions/from" 84 | }, 85 | "to": { 86 | "$ref": "#/definitions/to" 87 | } 88 | } 89 | }, 90 | "from": { 91 | "type": "integer", 92 | "description": "The beginning of the range of characters that this characterStyle applies to. Based on initial index of 0. For example a style applied to only the first two characters would be from=0 and to=1", 93 | "minimum": 0 94 | }, 95 | "to": { 96 | "type": "integer", 97 | "description": "The ending of the range of characters that this characterStyle applies to. Based on initial index of 0. For example a style applied to only the first two characters would be from=0 and to=1", 98 | "minimum": 0 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/pages/getting-started/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Authentication 3 | description: Page for Authentication 4 | contributors: 5 | - https://github.com/khound 6 | --- 7 | # Getting started with Photoshop and Lightroom API 8 | 9 | The first step in accessing the Photoshop and Lightroom APIs is getting authenticated. For that you will need an Authorization Token and an API Key. With the steps below, we'll show you how to gain access and make your first `hello world` call. 10 | 11 | ## Get access 12 | 13 | Here are the steps to get started with the Photoshop and Lightroom APIs. 14 | 15 | ### Getting started from Developer Console 16 | 17 | If you *have* already been provisioned with access through your organization you will need to create a project in developer console. If you have already got your API key, you can skip these steps. 18 | 1. Go to https://developer.adobe.com/console/home and **sign in to the Developer Console**. 19 | 2. Select **Create new project** under the **Quick start** section on the middle of your screen: 20 | ![Screenshot](images/CreateNewProjectConsole.png) 21 | 3. Choose **Add API**: 22 | ![Screenshot](images/AddAPIConsole.png) 23 | 4. Select the **Photoshop - Firefly and Creative Cloud Automation** and click on **Next**: 24 | ![Screenshot](images/AddAPIConsolePSFF.png) 25 | 5. Select **Save configured API**: 26 | ![Screenshot](images/ServicePrincipalConsole.png) 27 | Default selection for type of Authentication is made for **OAuth Server-to-Server** and you should keep it. Service Account(JWT) authentication will be deprecated soon. 28 | 6. Add the Lightroom API to your project by clicking on **Add to Project** and selecting **API** 29 | ![Screenshot](images/AddAnotherAPI.png) 30 | 7. Select the **Lightroom - Firefly and Creative Cloud Automation** and click on **Next**: 31 | ![Screenshot](images/AddAPIConsoleLRFF.png) 32 | Repeat step 5 33 | 8. Repeat step 6 and select **Remove Background - Firefly and Creative Cloud Automation** and click on **Next**: 34 | ![Screenshot](images/AddAPIConsoleRBFF.png) 35 | Repeat step 5 36 | 9. Select **Generate access token**: 37 | ![Screenshot](images/GenerateAccessTokenFromConsole.png) 38 | 10. Congratulations! You have just created a token. You can **copy** the token : 39 | ![Screenshot](images/AccessTokenCurlConsole.png) 40 | 11. Once you’ve created your token, you can follow the steps below to make your first API call. 41 | - Open your terminal and paste the code below. 42 | - Replace the variables "YOUR_ACCESS_TOKEN" with the token you generated on Adobe I/O Console. 43 | - Replace . You can find this on the same page you generated your token on. 44 | - Once all variables have been replaced you can run the command. 45 | 46 | ``` shell 47 | curl --request GET \ 48 | --url https://image.adobe.io/pie/psdService/hello \ 49 | --header "Authorization: Bearer " \ 50 | --header "x-api-key: " 51 | ``` 52 | 53 | If you are using Windows machine don't use the backslash for the curl commands. e.g 54 | ``` shell 55 | curl --request GET --url https://image.adobe.io/pie/psdService/hello --header "Authorization: Bearer " --header "x-api-key: " 56 | ``` 57 | Congratulations! You just made your first request to the Photoshop API. 58 | 59 | ## Automate Token 60 | Note that your token will expire every 60 minutes and will need to be refreshed after it expires. You can automate the token generation by referring to our sample code in node.js [here](https://github.com/AdobeDocs/cis-photoshop-api-docs/blob/main/sample-code/service-principal-sample-app/index.js) 61 | 62 | ## Build something cool# 63 | You have now Access Token and Client Id. You can use that to build your application using Photoshop API. 64 | Check out this SDK and API documentation for that. 65 | - [Photoshop API SDK](https://github.com/adobe/adobe-photoshop-api-sdk#readme) 66 | - [Photoshop API Documentation](../api/) 67 | -------------------------------------------------------------------------------- /static/acr/post_image_edit.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "post_image_edit.schema.json", 4 | "title": "post_image_edit", 5 | "description": "Initiates an asynchronous job to edit an image", 6 | "type": "object", 7 | "required": [ 8 | "inputs", 9 | "outputs", 10 | "options" 11 | ], 12 | "properties": { 13 | "inputs": { 14 | "type": "object", 15 | "minProperties": 1, 16 | "description": "The input assets for your call", 17 | "required": [ 18 | "source" 19 | ], 20 | "properties": { 21 | "source": { 22 | "$ref": "inputs.schema.json#/definitions/inputs" 23 | } 24 | } 25 | }, 26 | "outputs": { 27 | "$ref": "outputs.schema.json#/definitions/outputs" 28 | }, 29 | "options": { 30 | "type": "object", 31 | "minProperties": 1, 32 | "additionalProperties": false, 33 | "properties": { 34 | "Exposure": { 35 | "type": "number", 36 | "minimum": -5, 37 | "maximum": 5, 38 | "multipleOf": 0.01 39 | }, 40 | "Saturation": { 41 | "type": "number", 42 | "minimum": -100, 43 | "maximum": 100 44 | }, 45 | "Contrast": { 46 | "type": "number", 47 | "minimum": -100, 48 | "maximum": 100 49 | }, 50 | "VignetteAmount": { 51 | "type": "number", 52 | "minimum": -100, 53 | "maximum": 100 54 | }, 55 | "Vibrance": { 56 | "type": "number", 57 | "minimum": -100, 58 | "maximum": 100 59 | }, 60 | "Highlights": { 61 | "type": "number", 62 | "minimum": -100, 63 | "maximum": 100 64 | }, 65 | "Shadows": { 66 | "type": "number", 67 | "minimum": -100, 68 | "maximum": 100 69 | }, 70 | "Whites": { 71 | "type": "number", 72 | "minimum": -100, 73 | "maximum": 100 74 | }, 75 | "Blacks": { 76 | "type": "number", 77 | "minimum": -100, 78 | "maximum": 100 79 | }, 80 | "Clarity": { 81 | "type": "number", 82 | "minimum": -100, 83 | "maximum": 100 84 | }, 85 | "Dehaze": { 86 | "type": "number", 87 | "minimum": -100, 88 | "maximum": 100 89 | }, 90 | "Texture": { 91 | "type": "number", 92 | "minimum": -100, 93 | "maximum": 100 94 | }, 95 | "Sharpness": { 96 | "type": "number", 97 | "minimum": 0, 98 | "maximum": 150 99 | }, 100 | "ColorNoiseReduction": { 101 | "type": "number", 102 | "minimum": 0, 103 | "maximum": 100 104 | }, 105 | "NoiseReduction": { 106 | "type": "number", 107 | "minimum": 0, 108 | "maximum": 100 109 | }, 110 | "SharpenDetail": { 111 | "type": "number", 112 | "minimum": 0, 113 | "maximum": 100 114 | }, 115 | "SharpenEdgeMasking": { 116 | "type": "number", 117 | "minimum": 0, 118 | "maximum": 100 119 | }, 120 | "SharpenRadius": { 121 | "type": "number", 122 | "minimum": 0.5, 123 | "maximum": 3, 124 | "multipleOf": 0.01 125 | }, 126 | "WhiteBalance": { 127 | "type": "string", 128 | "enum": [ 129 | "As Shot", 130 | "Auto", 131 | "Cloudy", 132 | "Custom", 133 | "Daylight", 134 | "Flash", 135 | "Fluorescent", 136 | "Shade", 137 | "Tungsten" 138 | ] 139 | } 140 | } 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /sample-code/service-principal-sample-app/README.md: -------------------------------------------------------------------------------- 1 | # Photoshop API Example: Node.js 2 | 3 | This sample app will show you how to use Adobe Photoshop APIs with Service Principal using Node.js. 4 | 5 | After setting up the sample, you will have a Node.js app that: 6 | 7 | 1. Generates a Service Principal for your credentials 8 | 1. Obtains an access token 9 | 1. Obtains a pre-signed url from AWS for Photoshop file in S3 10 | 1. Get the document manifest from the Photoshop file 11 | 1. Obtains a pre-signed PUT url for saving a rendition 12 | 1. Create a jpeg rendition for the Photoshop file 13 | 1. Add an adjustment layer to the file and save to another pre-signed PUT url 14 | 15 | 16 | 17 | 18 | 19 | 20 | - [Technology Used](#technology-used) 21 | - [Prerequisites](#prerequisites) 22 | - [Configuration](#configuration) 23 | - [Install Node.js packages](#install-nodejs-packages) 24 | - [Set your Adobe API credentials](#set-your-adobe-api-credentials) 25 | - [Specify the location of a sample file](#specify-the-location-of-a-sample-file) 26 | - [Obtain AWS credentials](#obtain-aws-credentials) 27 | - [Usage](#usage) 28 | - [Other Resources](#other-resources) 29 | 30 | 31 | 32 | ## Technology Used 33 | 34 | 1. Node.js 10 or higher and the `npm` package manager 35 | 1. OpenSSL CLI 36 | 37 | ## Prerequisites 38 | 39 | Please be sure to follow the instructions about obtaining your credentials [here](https://developer.adobe.com/photoshop/photoshop-api-docs/getting-started/) 40 | 41 | You will also need an AWS account with access to S3. 42 | 43 | ## Configuration 44 | 45 | The following steps will help you get this sample up and running. 46 | 47 | ### Install Node.js packages 48 | 49 | The `package.json` file contains a list of dependencies. Run the following command from the top level directory of the app to install these dependencies: 50 | 51 | ```bash 52 | cd .. 53 | npm install 54 | ``` 55 | 56 | ### Set your Adobe API credentials 57 | 58 | Set your Adobe API credentials in the file `config.json` on these lines: 59 | 60 | ```json 61 | "client_id": "", 62 | "client_secret": "" 63 | ``` 64 | 65 | ### Specify the location of a sample file 66 | 67 | In `config.json`, provide an AWS S3 bucket and prefix for the sample Photoshop file. 68 | 69 | ```json 70 | "sample_file": { 71 | "s3_bucket": "", 72 | "s3_region": "", 73 | "s3_prefix": "", 74 | "s3_rendition_prefix": "", 75 | "rendition_type": "", 76 | "rendition_width": "", 77 | "s3_add_layer_prefix": "" 78 | } 79 | ``` 80 | 81 | ### Obtain AWS credentials 82 | 83 | You will need an AWS account to use this sample as is. Ensure AWS credentials are available for the sample app. See [Setting Credentials in Node.js](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-credentials-node.html) 84 | 85 | ## Usage 86 | 87 | Now, run the app: 88 | 89 | ```bash 90 | node index.js 91 | ``` 92 | 93 | The app will write output to the console to show progress and results. Many of the outputs are numbered so that you can match them up to the corresponding locations in the code. 94 | 95 | ## Other Resources 96 | 97 | - [Adobe Photoshop API Documentation](https://developer.adobe.com/photoshop/photoshop-api-docs/api/) 98 | - [Adobe Photoshop API SDK](https://github.com/adobe/adobe-photoshop-api-sdk#readme) 99 | -------------------------------------------------------------------------------- /static/acr/outputs.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "outputs.schema.json", 4 | "title": "a file output obect", 5 | "description": "Represents the collective fields needed to indicate an output file, destination and format", 6 | "definitions": { 7 | "output": { 8 | "type": "object", 9 | "description": "An object describing the requested file outputs (a new psd file or supported renditions)", 10 | "required": [ 11 | "href", 12 | "storage", 13 | "type" 14 | ], 15 | "properties": { 16 | "storage": { 17 | "$ref": "inputs.schema.json#/definitions/storage" 18 | }, 19 | "href": { 20 | "$ref": "inputs.schema.json#/definitions/href" 21 | }, 22 | "type": { 23 | "description": "Desired output image format", 24 | "enum": [ 25 | "image/jpeg", 26 | "image/x-adobe-dng", 27 | "image/png", 28 | "application/rdf+xml" 29 | ], 30 | "type": "string" 31 | }, 32 | "overwrite": { 33 | "description": "If the output file already exists should it be overwritten.`overwrite` flag is used only when `storage = \"adobe\"`", 34 | "type": "boolean", 35 | "default": true 36 | }, 37 | "quality": { 38 | "description": "Quality of the JPEG outputs (will be ignored for other output types). Ranges from 0 to 12, with 12 as the highest quality.", 39 | "type": "number", 40 | "default": 12, 41 | "minimum": 0, 42 | "maximum": 12 43 | } 44 | }, 45 | "allOf": [ 46 | { 47 | "if": { 48 | "properties": { 49 | "type": { 50 | "pattern": "image/jpeg" 51 | } 52 | } 53 | }, 54 | "then": { 55 | "properties": { 56 | "quality": { 57 | "description": "Desired JPEG image quality, integers range from 0 to 12", 58 | "type": "number", 59 | "minimum": 0, 60 | "maximum": 12 61 | } 62 | } 63 | } 64 | }, 65 | { 66 | "if": { 67 | "properties": { 68 | "storage": { 69 | "pattern": "(^azure|external|dropbox$)", 70 | "description": "Asset stored on an external service (like AWS S3, Azure, Dropbox etc.). If you are using presigned url for dropbox or azure, use `storage=\"dropbox\"` or `storage=\"azure\"` else it is `storage=\"external\"`" 71 | } 72 | } 73 | }, 74 | "then": { 75 | "properties": { 76 | "href": { 77 | "format": "uri", 78 | "pattern": "^https://", 79 | "description": "Any public url or a presignedURL for the asset output" 80 | } 81 | } 82 | }, 83 | "else": { 84 | "properties": { 85 | "href": { 86 | "pattern": "^/?(temp|cloud-content|assets|pubs)/.*", 87 | "description": "A string representing the path to the output file stored on Adobe's cloud.
Not available for the integrations created with JWT authentication or Service Principle." 88 | }, 89 | "storage": { 90 | "description" : "Asset stored on Adobe's cloud `adobe`.
Not available for the integrations created with JWT authentication or Service Principle." 91 | } 92 | } 93 | } 94 | } 95 | ] 96 | }, 97 | "outputs": { 98 | "type": "array", 99 | "minItems": 1, 100 | "maxItems": 25, 101 | "description": "An array of output objects. each output object will be either 'external' or 'adobe'. Maximum limit to generate output files in one API call is 25.", 102 | "items": { 103 | "$ref": "#/definitions/output" 104 | } 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /static/PITS/fontColor.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "fontColor.schema.json", 4 | "title": "a font color obect", 5 | "description": "The font colors of the textStyles in textLayer in 16bit representation. Only applicable for the layer types: ['textLayer']", 6 | "definitions": { 7 | "fontColor": { 8 | "type": "object", 9 | "minProperties": 1, 10 | "description": "The font color settings. It can be in one of the formats `rgb`, `cmyk`, `gray`, `lab`", 11 | "anyOf": [{ 12 | "properties": { 13 | "rgb": { 14 | "type": "object", 15 | "minProperties": 1, 16 | "anyOf": [{ 17 | "properties": { 18 | "red": { 19 | "type": "integer", 20 | "description": "The color red value", 21 | "minimum": 0, 22 | "maximum": 65535 23 | }, 24 | "green": { 25 | "type": "integer", 26 | "description": "The color green value", 27 | "minimum": 0, 28 | "maximum": 65535 29 | }, 30 | "blue": { 31 | "type": "integer", 32 | "description": "The color blue value", 33 | "minimum": 0, 34 | "maximum": 65535 35 | } 36 | } 37 | }], 38 | "description": "fontColor in rgb format" 39 | }, 40 | "lab": { 41 | "type": "object", 42 | "minProperties": 1, 43 | "anyOf": [{ 44 | "properties": { 45 | "luminance": { 46 | "type": "integer", 47 | "description": "The color luminance value", 48 | "minimum": 0, 49 | "maximum": 65535 50 | }, 51 | "a": { 52 | "type": "integer", 53 | "description": "The color a value", 54 | "minimum": 0, 55 | "maximum": 65535 56 | }, 57 | "b": { 58 | "type": "integer", 59 | "description": "The color b value", 60 | "minimum": 0, 61 | "maximum": 65535 62 | } 63 | } 64 | }], 65 | "description": "fontColor in lab format" 66 | }, 67 | "gray": { 68 | "type": "object", 69 | "minProperties": 1, 70 | "required": ["gray"], 71 | "description": "fontColor in gray format", 72 | "properties": { 73 | "gray": { 74 | "type": "integer", 75 | "description": "The color gray value", 76 | "minimum": 0, 77 | "maximum": 65535 78 | } 79 | } 80 | }, 81 | "cmyk": { 82 | "type": "object", 83 | "minProperties": 1, 84 | "anyOf": [{ 85 | "properties": { 86 | "cyan": { 87 | "type": "integer", 88 | "description": "The color cyan value", 89 | "minimum": 0, 90 | "maximum": 65535 91 | }, 92 | "magenta": { 93 | "type": "integer", 94 | "description": "The color magenta value", 95 | "minimum": 0, 96 | "maximum": 65535 97 | }, 98 | "yellowColor": { 99 | "type": "integer", 100 | "description": "The color yellow value", 101 | "minimum": 0, 102 | "maximum": 65535 103 | }, 104 | "black": { 105 | "type": "integer", 106 | "description": "The color black value", 107 | "minimum": 0, 108 | "maximum": 65535 109 | } 110 | } 111 | } 112 | ], 113 | "description": "fontColor in cmyk format" 114 | } 115 | } 116 | }] 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /sample-code/ic-customized-workflow-app/IC_customized_workflow_using_cc_storage.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # this is a demo code snippet to use Remove Background api to generate remove background result as Photoshop path (Use Adobe Creative Cloud Storage) 3 | 4 | # set up authorization token variable, by default it is the first argument 5 | token='Your_Access_Token' 6 | 7 | # set api key / client id 8 | api_key='Your_Client_Id' 9 | 10 | # set endpoint for Remove Background api. API doc: https://developer.adobe.com/photoshop/photoshop-api-docs/api/#tag/Photoshop 11 | ic_endpoint='https://image.adobe.io/sensei/cutout' 12 | 13 | # set endpoint for Pegasus action api. API doc: https://adobedocs.github.io/photoshop-api-docs/#api-Photoshop-photoshopActions 14 | pegasus_endpoint='https://image.adobe.io/pie/psdService/photoshopActions' 15 | 16 | 17 | # This is the input file URL 18 | input_url='A file URL for input image file' 19 | 20 | # This is the URL for action file. Please download the make-path.atn and upload to your CC storage location 21 | action_url='A file URL for action file (make-path.atn file downloaded)' 22 | 23 | # This is the URL for intermediate result file. 24 | intermediate_output_url='A file URL for intermediate result' 25 | 26 | # This is the file URL final output. You will need to checkout the final Remove Background result with path from here. 27 | final_output_url='A file URL for final result' 28 | 29 | 30 | #--------------------------------------------- Call Sensei Remove Background Service ----------------------------------------- 31 | # call Remove Background API 32 | 33 | ic_post_response=$( 34 | curl -s $ic_endpoint \ 35 | -H "Authorization: Bearer $token" \ 36 | -H "x-api-key: $api_key" \ 37 | -d '{ 38 | "input": { 39 | "storage":"external", 40 | "href": "'$input_url'" 41 | }, 42 | "output": { 43 | "storage":"external", 44 | "href": "'$intermediate_output_url'", 45 | "mask": { 46 | "format":"soft" 47 | }, 48 | "overwrite":true 49 | } 50 | }' 51 | ) 52 | 53 | ic_status_endpoint=$(jq -r '._links.self.href' <<< $ic_post_response) 54 | 55 | 56 | # waiting for Remove Background service result to be ready 57 | end=$((SECONDS+20)) # wait for 20 seconds 58 | 59 | 60 | while [[ $SECONDS -lt $end && "$ic_status" != "succeeded" ]]; do 61 | : 62 | ic_status_response=$( 63 | curl -s $ic_status_endpoint \ 64 | -H "Authorization: Bearer $token" \ 65 | -H "x-api-key: $api_key" 66 | ) 67 | ic_status=$(jq -r '.status' <<< $ic_status_response) 68 | echo ${ic_status} 69 | sleep 1 70 | 71 | done 72 | 73 | #------------------------------------------------------------------------------------------------------------------ 74 | 75 | 76 | 77 | #--------------------------------------------- Call Remove Background Service ----------------------------------------- 78 | # call Photoshop action API 79 | 80 | pegasus_response=$( 81 | curl -s $pegasus_endpoint \ 82 | -H "Authorization: Bearer $token" \ 83 | -H "x-api-key: $api_key" \ 84 | -X POST \ 85 | -d '{ 86 | "inputs": [ 87 | { 88 | "href": "'$intermediate_output_url'", 89 | "storage": "adobe" 90 | } 91 | ], 92 | "options": { 93 | "actions": [ 94 | { 95 | "href": "'$action_url'", 96 | "storage": "adobe" 97 | } 98 | ] 99 | }, 100 | "outputs": [ 101 | { 102 | "storage": "external", 103 | "type": "image/jpeg" 104 | "href": "'final_output_url'" 105 | } 106 | ] 107 | }' 108 | ) 109 | echo ${pegasus_response} 110 | 111 | pegasus_status_endpoint=$(jq -r '._links.self.href' <<< $pegasus_response) 112 | 113 | 114 | # waiting for Pegasus service result to be ready 115 | end=$((SECONDS+20)) # almost wait 20 seconds 116 | 117 | while [[ $SECONDS -lt $end && "$pegasus_status" != "succeeded" ]]; do 118 | : 119 | pegasus_status_response=$( 120 | curl -s $pegasus_status_endpoint \ 121 | -H "Authorization: Bearer $token" \ 122 | -H "x-api-key: $api_key" 123 | ) 124 | pegasus_status=$(jq -r '.outputs[0].status' <<< $pegasus_status_response) 125 | echo ${pegasus_status} 126 | sleep 0.5 127 | 128 | done 129 | 130 | #------------------------------------------------------------------------------------------------------------------ 131 | 132 | 133 | # Note: Please check out the final result under the location where final_output_url was generated from. 134 | # The final result should be in JPEG format with path embedded. Please open the result file in Photoshop and check the 135 | # path panel 136 | echo "\nScript completed !" 137 | -------------------------------------------------------------------------------- /static/PITS/post_document_create.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "post_document_create.schema.json", 4 | "title": "post_document_create", 5 | "description": "Initiates an asynchronous job to create a new psd and/or renditions", 6 | "type": "object", 7 | "required": [ 8 | "options", 9 | "outputs" 10 | ], 11 | "properties": { 12 | "options": { 13 | "type": "object", 14 | "description": "User can create a document using the options block.", 15 | "required": [ 16 | "document" 17 | ], 18 | "properties": { 19 | "document": { 20 | "type": "object", 21 | "minProperties": 1, 22 | "description": "Document object with params to be created. All of `height`, `width`, `resolution`, `mode` and `fill` required", 23 | "allOf": [{ 24 | "required": [ 25 | "height" 26 | ] 27 | }, 28 | { 29 | "required": [ 30 | "width" 31 | ] 32 | }, 33 | { 34 | "required": [ 35 | "resolution" 36 | ] 37 | }, 38 | { 39 | "required": [ 40 | "mode" 41 | ] 42 | }, 43 | { 44 | "required": [ 45 | "fill" 46 | ] 47 | } 48 | ], 49 | "properties": { 50 | "height": { 51 | "type": "integer", 52 | "description": "In pixels" 53 | }, 54 | "width": { 55 | "type": "integer", 56 | "description": "In pixels" 57 | }, 58 | "resolution": { 59 | "type": "integer", 60 | "minimum": 72, 61 | "maximum": 300, 62 | "description": "In pixels per inch" 63 | }, 64 | "fill": { 65 | "type": "string", 66 | "enum": [ 67 | "white", 68 | "backgroundColor", 69 | "transparent" 70 | ], 71 | "description": "Type of fill for the background layer" 72 | }, 73 | "mode": { 74 | "type": "string", 75 | "enum": [ 76 | "bitmap", 77 | "greyscale", 78 | "indexed", 79 | "rgb", 80 | "cmyk", 81 | "hsl", 82 | "hsb", 83 | "multichannel", 84 | "duotone", 85 | "lab", 86 | "xyz" 87 | ], 88 | "description": "Color space" 89 | }, 90 | "depth": { 91 | "type": "integer", 92 | "enum": [ 93 | 8, 94 | 16, 95 | 32 96 | ], 97 | "description": "Bit depth, this is either 8, 16 or 32 bit" 98 | } 99 | } 100 | }, 101 | "layers": { 102 | "$ref": "layers_create.schema.json#/definitions/layer_objects", 103 | "description": "An array of layer objects representing the layers to be created, in the same order as provided (from top to bottom)." 104 | }, 105 | "globalFont": { 106 | "type": "string", 107 | "description": "The full postscript name of the font to be used as the global default for the document. This font will be used for any text layer which has a missing font and no other font has been specifically provided for that layer. If this font itself is missing, the option specified for manageMissingFonts from above will take effect." 108 | }, 109 | "fonts": { 110 | "$ref": "file_input.schema.json#/definitions/input_objects", 111 | "description": "Array of custom fonts needed in this document" 112 | }, 113 | "manageMissingFonts": { 114 | "enum": [ 115 | "fail", 116 | "useDefault" 117 | ], 118 | "default": "useDefault", 119 | "description": "Action to take if there are one or more missing fonts in the document. `fail` - The job will not succeed and the status will be set to `failed`, with the details of the error provided in the `details` section in the status.`useDefault` - The job will succeed, however, by default all the missing fonts will be replaced with this font: ArialMT" 120 | } 121 | } 122 | }, 123 | "outputs": { 124 | "$ref": "file_output.schema.json#/definitions/output_objects" 125 | } 126 | }, 127 | "additionalProperties": false 128 | } 129 | -------------------------------------------------------------------------------- /src/pages/general-workflow/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: General Workflow of Photoshop API 3 | description: General Workflow of Photoshop API 4 | --- 5 | # General Workflow for our API 6 | 7 | The typical workflow involves making one or more calls to our API, to edit PSD or other image files, and to create new image renditions. 8 | 9 | As you begin integrating the Ps APIs into your workflow, there are a few considerations to keep in mind which we've outlined below: 10 | 11 | ## Input and Output file storage 12 | 13 | The Photoshop API works with any public or signed url. We have documented a few of the most common storage services and how to generate the urls programmatically. 14 | 15 | **AWS S3:** Pre-signed GET/PUT URL. For more information about pre-signed urls on S3 you can go [here](https://docs.aws.amazon.com/AmazonS3/latest/userguide/PresignedUrlUploadObject.html). Here are some code samples that show you how to generate your pre-signed urls programmatically: 16 | - [Node.js](https://github.com/AdobeDocs/cis-photoshop-api-docs/tree/main/sample-code/storage-app/aws-s3/presignedURLs.js)
Please note that creating pre-signed urls for AWS S3 requires signature version S3V4, as demonstrated in the sample code. 17 | - [Python](https://github.com/AdobeDocs/cis-photoshop-api-docs/tree/main/sample-code/storage-app/azure/presignedURLs.py) 18 | 19 | 20 | We also have a python [application](https://github.com/AdobeDocs/cis-photoshop-api-docs/tree/main/sample-code/storage-app/aws-s3/example.py) that provides a working example of how to call our api using assets stored in AWS S3. 21 | 22 | **Google Drive:**: Signed GET/PUT URL. For more information on how to setup your Google drive account for access to creating a signed URL [here](https://www.labnol.org/google-api-service-account-220404). Here are some code samples for getting signed urls. 23 | - [Node.js](https://github.com/AdobeDocs/cis-photoshop-api-docs/tree/main/sample-code/storage-app/googledrive/presignedURLs.js) 24 | 25 | **Azure:** SAS (Shared Access Signature) for upload/download. For more information on how to generate a Shared Access Signature you can go [here](https://azuresdkdocs.blob.core.windows.net/$web/python/azure-storage-blob/12.9.0/index.html). Here are some code samples for generating a url with Shared Access Signature. 26 | - [Node.js](https://github.com/AdobeDocs/cis-photoshop-api-docs/tree/main/sample-code/storage-app/azure/presignedURLs.js) 27 | - [Python](https://github.com/AdobeDocs/cis-photoshop-api-docs/tree/main/sample-code/storage-app/azure/presignedURLs.py) 28 | 29 | **Dropbox:** Temporary upload/download URLs. For more information on how to generate an upload/download you can go [here](https://www.dropbox.com/developers/documentation). You can also create a file upload link for dropbox [here](https://www.dropbox.com/developers/documentation/http/documentation#files-get_temporary_upload_link). 30 | 31 | 32 | **Note :** You can test to see if your public url or presigned url is working. 33 | 34 | Run the curl command below to see if your input file path is working 35 | ``` 36 | curl -X GET --output 37 | ``` 38 | If you are using a presigned url, put your file path within "" 39 | ``` 40 | curl -X GET "" --output 41 | ``` 42 | Run the curl command below to see if your output file path is working 43 | ``` 44 | curl -X PUT -d 45 | ``` 46 | If you are using a presigned url, put your file path within "" 47 | ``` 48 | curl -X PUT "" -d 49 | ``` 50 | 51 | 52 | ## Current Limitations 53 | There are a few limitations to the APIs you should be aware of ahead of time. 54 | - Multi-part uploads and downloads are not yet supported. 55 | - All the endpoints only support a single file input. 56 | - Error handling is a work in progress. Sometimes you may not see the most helpful of messages. 57 | 58 | ## Retries 59 | For increased reliability and stability we have added a retry mechanism for all API calls, and have some recommendations on how to handle these: 60 | - The service will retry status codes of 429, 502, 503, 504 three times. 61 | - You should only retry requests that have a 5xx response code. A 5xx error response indicates there was a problem processing the request on the server. 62 | - You should implement an exponential back-off retry strategy with 3 retry attempts. 63 | - You should not retry requests for any other response code. 64 | 65 | ## Compatibility with Photoshop versions 66 | 67 | - The APIs will open any PSD created with Photoshop 1.0 or later. 68 | - When saving as PSD, the APIs will create PSDs compatible with the current shipping Photoshop. 69 | - In regards to "maximize compatibility" referenced in https://helpx.adobe.com/photoshop/using/file-formats.html#maximize_compatibility_for_psd_and_psb_files the API's default to “yes” 70 | -------------------------------------------------------------------------------- /sample-code/ic-customized-workflow-app/IC_customized_workflow_using_S3.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # this is a demo code snippet to use Remove Background api to generate cutout result as Photoshop path (use AWS S3 storage) 3 | 4 | # set up authorization token variable, by default it is the first argument 5 | token='Your_Access_Token' 6 | 7 | # set api key / client id 8 | api_key='Your_Client_Id' 9 | 10 | # set endpoint for Remove Background api. API doc: https://adobedocs.github.io/photoshop-api-docs/#api-Sensei-cutout 11 | ic_endpoint='https://image.adobe.io/sensei/cutout' 12 | 13 | # set endpoint for Pegasus action service. API doc: https://adobedocs.github.io/photoshop-api-docs/#api-Photoshop-photoshopActions 14 | pegasus_endpoint='https://image.adobe.io/pie/psdService/photoshopActions' 15 | 16 | 17 | # This is the input presign URL 18 | input_url='A presigned GET URL for input image file' 19 | 20 | # This is the presign URL for action file. Please download the make-path.atn and upload to your own S3 location 21 | action_url='A presigned GET URL for action file (make-path.atn file downloaded)' 22 | 23 | # This is a presign PUT URL for intermediate output in the chaining process (Remove Background api will populate the file to this location) 24 | intermediate_output_put_url='A presigned PUT URL for intermediate result' 25 | 26 | # This is a presign PUT URL for intermediate output in the chaining process (Photoshop action service will use intermediate results from above) 27 | intermediate_output_get_url='A presigned GET URL for intermediate result' 28 | 29 | 30 | # This is a presign PUT URL for final output. You will need to checkout the final cutout result with path from here. 31 | final_output_url='A presigned PUT URL for final result' 32 | 33 | 34 | #--------------------------------------------- Call Remove Background API ----------------------------------------- 35 | # call Remove Background API 36 | 37 | ic_post_response=$( 38 | curl -s $ic_endpoint \ 39 | -H "Authorization: Bearer $token" \ 40 | -H "x-api-key: $api_key" \ 41 | -d '{ 42 | "input": { 43 | "storage":"external", 44 | "href": "'$input_url'" 45 | }, 46 | "output": { 47 | "storage":"external", 48 | "href": "'intermediate_output_put_url'", 49 | "mask": { 50 | "format":"soft" 51 | } 52 | } 53 | }' 54 | ) 55 | 56 | ic_status_endpoint=$(jq -r '._links.self.href' <<< $ic_post_response) 57 | 58 | 59 | # waiting for Remove Background api result to be ready 60 | end=$((SECONDS+20)) # wait for 20 seconds 61 | 62 | # Initialize ic status 63 | ic_status='null' 64 | 65 | while [[ $SECONDS -lt $end && "$ic_status" != "succeeded" ]]; do 66 | : 67 | ic_status_response=$( 68 | curl -s $ic_status_endpoint \ 69 | -H "Authorization: Bearer $token" \ 70 | -H "x-api-key: $api_key" 71 | ) 72 | ic_status=$(jq -r '.status' <<< $ic_status_response) 73 | echo ${ic_status} 74 | sleep 1 75 | 76 | done 77 | 78 | #------------------------------------------------------------------------------------------------------------------ 79 | 80 | 81 | 82 | #--------------------------------------------- Call Remove Background API ----------------------------------------- 83 | # call Photoshop action API 84 | 85 | pegasus_response=$( 86 | curl -s $pegasus_endpoint \ 87 | -H "Authorization: Bearer $token" \ 88 | -H "x-api-key: $api_key" \ 89 | -X POST \ 90 | -d '{ 91 | "inputs": [ 92 | { 93 | "href": "'intermediate_output_get_url'", 94 | "storage": "external" 95 | } 96 | ], 97 | "options": { 98 | "actions": [ 99 | { 100 | "href": "'$action_url'", 101 | "storage": "external" 102 | } 103 | ] 104 | }, 105 | "outputs": [ 106 | { 107 | "storage": "external", 108 | "type": "image/jpeg", 109 | "href": "'$final_output_url'" 110 | } 111 | ] 112 | }' 113 | ) 114 | echo ${pegasus_response} 115 | 116 | pegasus_status_endpoint=$(jq -r '._links.self.href' <<< $pegasus_response) 117 | 118 | 119 | # waiting for Pegasus api result to be ready 120 | end=$((SECONDS+20)) # almost wait 20 seconds 121 | 122 | while [[ $SECONDS -lt $end && "$pegasus_status" != "succeeded" ]]; do 123 | : 124 | pegasus_status_response=$( 125 | curl -s $pegasus_status_endpoint \ 126 | -H "Authorization: Bearer $token" \ 127 | -H "x-api-key: $api_key" 128 | ) 129 | pegasus_status=$(jq -r '.outputs[0].status' <<< $pegasus_status_response) 130 | echo ${pegasus_status} 131 | sleep 0.5 132 | 133 | done 134 | 135 | #------------------------------------------------------------------------------------------------------------------ 136 | 137 | 138 | # Note: Please check out the final result under the location where final_output_url was generated from. 139 | # The final result should be in JPEG format with path embedded. Please open the result file in Photoshop and check the 140 | # path panel 141 | echo "\nScript completed !" 142 | -------------------------------------------------------------------------------- /static/PITS/adjustments.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "adjustments.schema.json", 4 | "title": "an adjustment object", 5 | "description": "adjustment layer attributes", 6 | "definitions": { 7 | "brightness_contrast": { 8 | "type": "object", 9 | "description": "Brightness and contrast settings", 10 | "minProperties": 1, 11 | "anyOf": [{ 12 | "properties": { 13 | "brightness": { 14 | "type": "integer", 15 | "description": "The adjustmentLayer's brightness", 16 | "minimum": -150, 17 | "maximum": 150, 18 | "default": 0 19 | }, 20 | "contrast": { 21 | "type": "integer", 22 | "description": "The adjustmentLayer's contrast", 23 | "minimum": -150, 24 | "maximum": 150, 25 | "default": 0 26 | } 27 | } 28 | }] 29 | }, 30 | "exposure": { 31 | "type": "object", 32 | "description": "Exposure settings", 33 | "minProperties": 1, 34 | "anyOf": [{ 35 | "properties": { 36 | "exposure": { 37 | "type": "number", 38 | "description": "The layer's exposure", 39 | "default": 0, 40 | "minimum": -20, 41 | "maximum": 20 42 | }, 43 | "offset": { 44 | "type": "number", 45 | "description": "The layer's offset.", 46 | "default": 0, 47 | "minimum": -0.5, 48 | "maximum": 0.5 49 | }, 50 | "gammaCorrection": { 51 | "type": "number", 52 | "description": "The layer's gammaCorrection.", 53 | "default": 1, 54 | "minimum": 0.01, 55 | "maximum": 9.99 56 | } 57 | } 58 | }] 59 | }, 60 | "hue_saturation": { 61 | "type": "object", 62 | "description": "Hue and saturation settings", 63 | "minProperties": 1, 64 | "anyOf": [{ 65 | "properties": { 66 | "colorize": { 67 | "type": "boolean", 68 | "description": "Colorize", 69 | "default": false 70 | }, 71 | "channels": { 72 | "type": "array", 73 | "minItems": 1, 74 | "description": "an array of hashes representing the 'master' channel (the remaining five channels of 'magentas', 'yellows', 'greens', etc are not yet supported)", 75 | "items": { 76 | "type": "object", 77 | "anyOf": [{ 78 | "properties": { 79 | "channel": { 80 | "type": "string", 81 | "enum": [ 82 | "master" 83 | ] 84 | }, 85 | "hue": { 86 | "type": "integer", 87 | "minimum": -180, 88 | "maximum": 180 89 | }, 90 | "saturation": { 91 | "type": "integer", 92 | "minimum": -100, 93 | "maximum": 100 94 | }, 95 | "lightness": { 96 | "type": "integer", 97 | "minimum": -100, 98 | "maximum": 100 99 | } 100 | } 101 | }] 102 | } 103 | } 104 | } 105 | }] 106 | }, 107 | "color_balance": { 108 | "type": "object", 109 | "description": "Color balance settings", 110 | "minProperties": 1, 111 | "anyOf": [{ 112 | "properties": { 113 | "preserveLuminosity": { 114 | "type": "boolean", 115 | "description": "preserveLuminosity" 116 | }, 117 | "shadowLevels": { 118 | "type": "array", 119 | "description": "Array of 3 ints", 120 | "items": { 121 | "type": "integer", 122 | "minimum": -100, 123 | "maximum": 100, 124 | "minItems": 3, 125 | "maxItems": 3 126 | } 127 | }, 128 | "midtoneLevels": { 129 | "type": "array", 130 | "description": "Array of 3 ints", 131 | "items": { 132 | "type": "integer", 133 | "minimum": -100, 134 | "maximum": 100, 135 | "minItems": 3, 136 | "maxItems": 3 137 | } 138 | }, 139 | "hightoneLevels": { 140 | "type": "array", 141 | "description": "Array of 3 ints", 142 | "items": { 143 | "type": "integer", 144 | "minimum": -100, 145 | "maximum": 100, 146 | "minItems": 3, 147 | "maxItems": 3 148 | } 149 | } 150 | } 151 | }] 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /static/PITS/post_depth_blur.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "post_depth_blur.schema.json", 4 | "title": "post_depth_blur_json", 5 | "description": "Initiates an asynchronous job to apply depth Blur Neural Filter", 6 | "type": "object", 7 | "required": [ 8 | "inputs", 9 | "outputs" 10 | ], 11 | "properties": { 12 | "inputs": { 13 | "$ref": "file_input.schema.json#/definitions/input_objects_max_1" 14 | }, 15 | "options": { 16 | "type": "object", 17 | "properties": { 18 | "focalDistance": { 19 | "type": "integer", 20 | "description": "The distance of the point to be in focus. 0 would be the nearest point, 100 would be the furthest point", 21 | "default": 0, 22 | "minimum": 0, 23 | "maximum": 100 24 | }, 25 | "focalRange": { 26 | "type": "integer", 27 | "description": "The range of the focal point", 28 | "default": 0, 29 | "minimum": 0, 30 | "maximum": 100 31 | }, 32 | "focalSelector": { 33 | "type": "object", 34 | "description": "Co-ordinates of the specific focal point to select", 35 | "allOf": [{ 36 | "properties": { 37 | "x": { 38 | "type": "number", 39 | "description": "X co-ordinate" 40 | }, 41 | "y": { 42 | "type": "number", 43 | "description": "Y co-ordinate" 44 | } 45 | }, 46 | "additionalProperties": false, 47 | "minProperties": 2 48 | }] 49 | }, 50 | "focusSubject": { 51 | "type": "boolean", 52 | "description": "If enabled uses selectsubject to automatically select the prominent subject for focus. Also would override focalDistance", 53 | "default": false 54 | }, 55 | "blurStrength": { 56 | "type": "integer", 57 | "description": "The amount of blur to apply", 58 | "default": 50, 59 | "minimum": 0, 60 | "maximum": 100 61 | }, 62 | "haze": { 63 | "type": "integer", 64 | "description": "The amount of haze to apply", 65 | "default": 0, 66 | "minimum": 0, 67 | "maximum": 100 68 | }, 69 | "temp": { 70 | "type": "integer", 71 | "description": "The value of the temperature to apply. -50 would be coldest and 50 would be the warmest setting", 72 | "default": 0, 73 | "minimum": -50, 74 | "maximum": 50 75 | }, 76 | "tint": { 77 | "type": "integer", 78 | "description": "The amount of the tint to apply", 79 | "default": 0, 80 | "minimum": -50, 81 | "maximum": 50 82 | }, 83 | "saturation": { 84 | "type": "integer", 85 | "description": "The amount of the saturation to apply. -50 implies fully unsaturated colors and 50 will fully saturate the colors", 86 | "default": 0, 87 | "minimum": -50, 88 | "maximum": 50 89 | }, 90 | "brightness": { 91 | "type": "integer", 92 | "description": "The amount of the brightness to apply", 93 | "default": 0, 94 | "minimum": -50, 95 | "maximum": 50 96 | }, 97 | "grain": { 98 | "type": "integer", 99 | "description": "The amount of the graining to add to the image", 100 | "default": 0, 101 | "minimum": 0, 102 | "maximum": 100 103 | } 104 | }, 105 | "allOf": [ 106 | { 107 | "not": { 108 | "required": [ 109 | "focusSubject", "focalSelector" 110 | ] 111 | } 112 | } 113 | ], 114 | "additionalProperties": false 115 | }, 116 | "outputs": { 117 | "$ref": "file_output_pegasus.schema.json#/definitions/output_objects" 118 | } 119 | } 120 | } -------------------------------------------------------------------------------- /sample-code/lr-sample-app/crs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 109 | 110 | 111 | default 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 0, 0 137 | 255, 255 138 | 139 | 140 | 141 | 142 | 0, 0 143 | 255, 255 144 | 145 | 146 | 147 | 148 | 0, 0 149 | 255, 255 150 | 151 | 152 | 153 | 154 | 0, 0 155 | 255, 255 156 | 157 | 158 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /static/ic/get_status.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "get_status_success.schema.json", 4 | "title": "get_status", 5 | "description": "Returns the status of a job.", 6 | "type": "object", 7 | "properties": { 8 | "jobId": { 9 | "type": "string", 10 | "description": "The job's id requested", 11 | "example": "f54e0fcb-260b-47c3-b520-de0d17dc2b67" 12 | }, 13 | "created": { 14 | "type": "string", 15 | "format": "YYYY-DD-MMThh:mm:ss.mmmmmZ", 16 | "description": "Created timestamp of the job." 17 | }, 18 | "modified": { 19 | "type": "string", 20 | "format": "YYYY-DD-MMThh:mm:ss.mmmmmZ", 21 | "description": "Modified timestamp of the job." 22 | }, 23 | "status": { 24 | "type": "string", 25 | "description": "The job status", 26 | "enum": [ 27 | "pending", 28 | "running", 29 | "succeeded", 30 | "failed" 31 | ], 32 | "example": "string" 33 | }, 34 | "metadata": { 35 | "type": "object", 36 | "properties": { 37 | "service": { 38 | "type": "object", 39 | "properties": { 40 | "version": { 41 | "type":"string", 42 | "enum":["4.0"], 43 | "default": "4.0", 44 | "description": "Version of the service" 45 | } 46 | } 47 | } 48 | } 49 | }, 50 | "output": { 51 | "type": "object", 52 | "properties": { 53 | "href": { 54 | "type": "string", 55 | "minLength": 1, 56 | "description": "A URI representing the path to the input file" 57 | }, 58 | "storage": { 59 | "description": "Is the asset stored on Adobe's cloud or an external service (like AWS S3, Azure, Dropbox)", 60 | "type": "string", 61 | "enum": [ 62 | "adobe", 63 | "external", 64 | "azure", 65 | "dropbox" 66 | ], 67 | "default": "external" 68 | }, 69 | "mask": { 70 | "type":"object", 71 | "required":["format"], 72 | "properties":{ 73 | "format":{ 74 | "type":"string", 75 | "enum":["soft","binary"], 76 | "default": "soft", 77 | "description": "A soft (feathered) mask or binary mask" 78 | } 79 | } 80 | }, 81 | "color": { 82 | "type":"object", 83 | "required":["space"], 84 | "properties":{ 85 | "space":{ 86 | "type":"string", 87 | "enum":["rgba","rgb"], 88 | "description": "Color space for the output image", 89 | "example": "rgb" 90 | } 91 | } 92 | } 93 | } 94 | }, 95 | "options":{ 96 | "type":"object", 97 | "properties":{ 98 | "optimize": { 99 | "type": "string", 100 | "enum":["performance","batch"], 101 | "default": "performance", 102 | "description": "The value 'performance' optimizes for speed. 'batch' ensures the job will ultimately run regardless of wait time" 103 | } 104 | } 105 | }, 106 | "errors": { 107 | "type": "array", 108 | "minItems": 1, 109 | "description" : "`errors` block will contain items only when there is an error from the API called. e.g if `/sensei/cutout` API throws an error we will see items in this `errors` block on the status API call", 110 | "items": { 111 | "properties": { 112 | "title": { 113 | "type": "string", 114 | "format": "string", 115 | "description": "A short, human-readable summary of the problem", 116 | "example": "Requested resource was not found" 117 | }, 118 | "type": { 119 | "type": "string", 120 | "format": "string", 121 | "description": "A machine-readable error type", 122 | "example": "ResourceNotFound" 123 | }, 124 | "code": { 125 | "type": "integer", 126 | "format": "int", 127 | "description": "A machine-readable error code", 128 | "example": 404 129 | }, 130 | "details": { 131 | "type": "object", 132 | "description": "Further descriptions of the exact error where details is substituted for a specific issue.", 133 | "properties": { 134 | "name": { 135 | "type": "string", 136 | "description": "Name for the detailed error.", 137 | "example": "" 138 | }, 139 | "reason": { 140 | "type": "string", 141 | "description": "Details of error reason.", 142 | "example": "Unable to access the input href" 143 | } 144 | } 145 | } 146 | } 147 | } 148 | }, 149 | "_links": { 150 | "type": "object", 151 | "properties": { 152 | "self": { 153 | "type": "object", 154 | "properties": { 155 | "href": { 156 | "type": "string", 157 | "description": "Link that client can use to track status.", 158 | "example": "https://image.adobe.io/sensei/status/f54e0fcb-260b-47c3-b520-de0d17dc2b67" 159 | } 160 | } 161 | } 162 | } 163 | } 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /sample-code/s3-smart-object-replacement/app.js: -------------------------------------------------------------------------------- 1 | let URL = require('url') 2 | let AWS = require('aws-sdk') 3 | const fs = require("fs") 4 | const request = require('request') 5 | const endpoint = "https://image.adobe.io/pie/psdService/smartObject" 6 | 7 | /**********************************************************************/ 8 | /**********************************************************************/ 9 | /*************** FILL IN THE FOLLOWING INFORMATION **********************/ 10 | /**********************************************************************/ 11 | /**********************************************************************/ 12 | // FILL OUT INFORMATION ABOUT YOUR ADOBE CREDENTIALS 13 | // VISIT https://developer.adobe.com/console/projects to obtain the following information 14 | const imsConfig = { 15 | clientId: "YOUR_ADOBE_CLIENT_ID", 16 | clientSecret: "YOUR_ADOBE_CLIENT_SECRET" 17 | }; 18 | 19 | // FILL OUT INFORMATION ABOUT YOUR AZURE BLOB STORAGE 20 | const s3BucketName = "YOUR_BUCKET_NAME"; 21 | const awsRegion = "YOUR_BUCKET_REGION" 22 | const s3InputPath = "PATH/TO/input.psd" 23 | const s3ReplacementImagePath = "PATH/TO/REPLACEMENT/image.png" 24 | const s3OutputPath = "PATH/TO/WHERE/YOU/WANT/THE/output.jpg"; 25 | 26 | // FILL OUT INFORMATION ABOUT THE PSD AND TEXTLAYER 27 | const smartObjectLayerName = "NAME_OF_THE_SMARTOBJECT_LAYER"; 28 | 29 | /**********************************************************************/ 30 | /**********************************************************************/ 31 | /**********************************************************************/ 32 | 33 | async function generateIMSToken() { 34 | const url = 'https://ims-na1.adobelogin.com/ims/token/v3'; 35 | const options = { 36 | method: 'POST', 37 | url: url, 38 | headers: { 39 | 'Content-Type': 'application/x-www-form-urlencoded' 40 | }, 41 | form: { 42 | grant_type: 'client_credentials', 43 | client_id: imsConfig.clientId, 44 | client_secret: imsConfig.clientSecret, 45 | scope: 'openid,AdobeID,read_organizations' 46 | } 47 | }; 48 | 49 | return new Promise((resolve, reject) => { 50 | request(options, (err, res, body) => { 51 | if(err || res.statusCode >= 400) { 52 | reject( err || body ) 53 | }else{ 54 | resolve( body ) 55 | } 56 | }) 57 | }) 58 | } 59 | 60 | async function getSignedURL(bucket, destKey, region, op){ 61 | let s3 = new AWS.S3({ region: region, apiVersion: '2006-03-01', signatureVersion: 'v4' }) 62 | let params = {Bucket: bucket, Key: destKey}; 63 | return new Promise((resolve, reject) => { 64 | s3.getSignedUrl(op, params, (err, url)=>{ 65 | if(err){ 66 | reject(err) 67 | }else{ 68 | resolve(url) 69 | } 70 | }); 71 | }) 72 | } 73 | 74 | async function postPhotoshopAPI(endpoint, apiKey, token, requestBody){ 75 | let options = { 76 | url: endpoint, 77 | method: 'POST', 78 | headers: { 79 | "Authorization": `Bearer ${token}`, 80 | "x-api-key": apiKey 81 | }, 82 | json: true, 83 | body: requestBody 84 | } 85 | 86 | return new Promise((resolve, reject) => { 87 | request(options, (err, res, body) => { 88 | if(err || res.statusCode >= 400) { 89 | reject( err || body ) 90 | }else{ 91 | resolve( body ) 92 | } 93 | }) 94 | }) 95 | } 96 | 97 | async function pollStatus(responseBody, apiKey, token){ 98 | let options = { 99 | url: responseBody._links.self.href, 100 | method: 'GET', 101 | headers: { 102 | "Authorization": `Bearer ${token}`, 103 | "x-api-key": apiKey 104 | }, 105 | json: true 106 | } 107 | 108 | return new Promise((resolve, reject) => { 109 | let pollFunction = () => { 110 | request(options, (err, res, body) => { 111 | console.log(body.jobId, body.outputs[0].status) 112 | if(err || res.statusCode >= 400) { 113 | clearInterval(intervalId) 114 | reject(err || res.statusCode) 115 | }else if(body.outputs[0].status == 'succeeded' || body.outputs[0].status == 'failed'){ 116 | clearInterval(intervalId) 117 | resolve( body ) 118 | } 119 | }) 120 | } 121 | let intervalId = setInterval(pollFunction, 1000) 122 | }) 123 | } 124 | 125 | 126 | async function main(){ 127 | let authDetails = await generateIMSToken(); 128 | let creds = JSON.parse(authDetails); 129 | let inputUrl = await getSignedURL(s3BucketName, s3InputPath, awsRegion, 'getObject') 130 | let replacementImageUrl = await getSignedURL(s3BucketName, s3ReplacementImagePath, awsRegion, 'getObject') 131 | let outputUrl = await getSignedURL(s3BucketName, s3OutputPath, awsRegion, 'putObject') 132 | 133 | let requestBody = { 134 | "inputs":[ 135 | { 136 | "href": inputUrl, 137 | "storage": "external" 138 | } 139 | ], 140 | "options":{ 141 | "layers":[ 142 | { 143 | "name": smartObjectLayerName, 144 | "input": { 145 | "href": replacementImageUrl, 146 | "storage": "external" 147 | } 148 | } 149 | ] 150 | }, 151 | "outputs":[ 152 | { 153 | "href": outputUrl, 154 | "storage": "external", 155 | "type": "image/jpeg" 156 | } 157 | ] 158 | } 159 | 160 | try{ 161 | let response = await postPhotoshopAPI(endpoint, imsConfig.clientId, creds.access_token, requestBody) 162 | let status = await pollStatus(response, imsConfig.clientId, creds.access_token) 163 | console.log(JSON.stringify(status, null, 2)) 164 | }catch(e){ 165 | console.error(e) 166 | } 167 | 168 | } 169 | 170 | main(); 171 | -------------------------------------------------------------------------------- /static/PITS/file_output_pegasus.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "file_output.schema.json", 4 | "title": "a file output obect", 5 | "description": "Represents the collective fields needed to indicate an output file, destination and format", 6 | "definitions": { 7 | "output_object": { 8 | "type": "object", 9 | "description": "An object describing the requested file outputs (a new psd file or supported renditions)", 10 | "required": [ 11 | "href", 12 | "storage", 13 | "type" 14 | ], 15 | "properties": { 16 | "storage": { 17 | "$ref": "file_input.schema.json#/definitions/storage" 18 | }, 19 | "href": { 20 | "type": "string", 21 | "minLength": 1 22 | }, 23 | "type": { 24 | "description": "desired image format. 'image/vnd.adobe.photoshop' specifies a PSD file", 25 | "enum": [ 26 | "image/gif", 27 | "image/jpeg", 28 | "image/png", 29 | "image/tiff", 30 | "image/vnd.adobe.photoshop", 31 | "vnd.adobe.photoshop" 32 | ], 33 | "type": "string" 34 | }, 35 | "overwrite": { 36 | "description": "if the output file already exists should it be overwritten. Will eventually support eTags", 37 | "type": "boolean", 38 | "default": true 39 | }, 40 | "compression": { 41 | "description": "Desired PNG compression level.", 42 | "enum": [ 43 | "small", 44 | "medium", 45 | "large" 46 | ], 47 | "type": "string" 48 | }, 49 | "quality": { 50 | "description": "desired JPEG image quality, integers range from 1 to 12", 51 | "type": "number", 52 | "minimum": 1, 53 | "maximum": 12 54 | } 55 | }, 56 | "allOf": [ 57 | { 58 | "if": { 59 | "properties": { 60 | "type": { 61 | "pattern": "image/jpeg" 62 | } 63 | } 64 | }, 65 | "then": { 66 | "properties": { 67 | "quality": { 68 | "description": "desired JPEG image quality, integers range from 1 to 12", 69 | "type": "number", 70 | "minimum": 1, 71 | "maximum": 12 72 | }, 73 | "compression": { 74 | "not": {} 75 | } 76 | } 77 | } 78 | }, 79 | { 80 | "if": { 81 | "properties": { 82 | "type": { 83 | "pattern": "image/png" 84 | } 85 | } 86 | }, 87 | "then": { 88 | "properties": { 89 | "compression": { 90 | "description": "desired PNG compression level: small, medium and large", 91 | "enum": [ 92 | "small", 93 | "medium", 94 | "large" 95 | ], 96 | "type": "string" 97 | }, 98 | "quality": { 99 | "type": "number", 100 | "not": {} 101 | } 102 | } 103 | } 104 | }, 105 | { 106 | "if": { 107 | "properties": { 108 | "storage": { 109 | "pattern": "(^azure|external|dropbox$)", 110 | "description": "Asset stored on an external service (like AWS S3, Azure, Dropbox). If you are using presigned url for dropbox or azure, use `storage=\"dropbox\"` or `storage=\"azure\"` else it is `storage=\"external\"`" 111 | } 112 | } 113 | }, 114 | "then": { 115 | "properties": { 116 | "href": { 117 | "type": "string", 118 | "pattern": "^https://", 119 | "description": "Any public url or a presignedURL for the asset output" 120 | } 121 | } 122 | }, 123 | "else": { 124 | "if" : { 125 | "properties": { 126 | "storage": { 127 | "pattern": "(^cclib$)" 128 | } 129 | } 130 | }, 131 | "then" : { 132 | "properties": { 133 | "href": { 134 | "pattern": "^/?(api)/.+", 135 | "description": "A string representing the path to the output CC Libraries file.
Not available for the integrations created with JWT authentication or Service Principle." 136 | } 137 | } 138 | }, 139 | "else" : { 140 | "properties": { 141 | "href": { 142 | "pattern": "^/?(temp|cloud-content|assets|pubs)/.+", 143 | "description": "A string representing the path to the output CC Storage file.
Not available for the integrations created with JWT authentication or Service Principle." 144 | } 145 | } 146 | } 147 | } 148 | } 149 | ] 150 | }, 151 | "output_objects": { 152 | "type": "array", 153 | "minItems": 1, 154 | "maxItems": 25, 155 | "description": "An array of hashes describing the output files. Output file format can be any of `psd`, `jpeg`, `png`, or `tiff` and storage type can be any of `external`, `adobe`, `azure` or `dropbox`. Maximum limit of 25 per request.", 156 | "items": { 157 | "$ref": "#/definitions/output_object" 158 | } 159 | } 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /static/ic/post_cutout.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema":"http://json-schema.org/draft-07/schema#", 3 | "$id":"post_cutout.schema.json", 4 | "title":"post_cutout", 5 | "type":"object", 6 | "required":[ 7 | "input", 8 | "output" 9 | ], 10 | "properties":{ 11 | "input":{ 12 | "type":"object", 13 | "description": "Maximum supported input file resolution is 10k by 10k", 14 | "required":["href","storage"], 15 | "properties":{ 16 | "href": { 17 | "type": "string", 18 | "minLength": 1 19 | }, 20 | "storage": { 21 | "type": "string", 22 | "enum": [ 23 | "external", 24 | "azure", 25 | "dropbox", 26 | "adobe" 27 | ], 28 | "default": "external" 29 | } 30 | }, 31 | "if": { 32 | "properties": { 33 | "storage": { 34 | "pattern": "(^azure|external|dropbox$)", 35 | "description": "Asset stored on an external service (like AWS S3, Azure, Dropbox). If you are using presigned url for dropbox or azure, use `storage=\"dropbox\"` or `storage=\"azure\"` else it is `storage=\"external\"`" 36 | } 37 | } 38 | }, 39 | "then": { 40 | "properties": { 41 | "href": { 42 | "type": "string", 43 | "pattern": "^https://", 44 | "description": "Any public url or a presignedURL for the asset input" 45 | } 46 | } 47 | }, 48 | "else": { 49 | "properties": { 50 | "href": { 51 | "pattern": "^/?(temp|cloud-content|assets)/.+", 52 | "description": "A string representing the path to the input file stored on Adobe's cloud.
Not available for the integrations created with JWT authentication or Service Principle." 53 | }, 54 | "storage": { 55 | "description" : "Asset stored on Adobe's cloud.
Not available for the integrations created with JWT authentication or Service Principle." 56 | } 57 | } 58 | } 59 | }, 60 | "options":{ 61 | "type":"object", 62 | "properties":{ 63 | "optimize": { 64 | "type": "string", 65 | "enum":["performance","batch"], 66 | "default": "performance", 67 | "description": "The value 'performance' optimizes for speed. 'batch' ensures the job will ultimately run regardless of wait time" 68 | }, 69 | "process": { 70 | "type": "object", 71 | "x-internal": true, 72 | "description": "process is not available for the integrations created with JWT authentication or Service Principle.", 73 | "properties": { 74 | "postprocess": { 75 | "type": "boolean" 76 | } 77 | } 78 | }, 79 | "service": { 80 | "type": "object", 81 | "properties": { 82 | "version": { 83 | "type":"string", 84 | "default": "4.0", 85 | "description": "Version of the service" 86 | } 87 | } 88 | } 89 | } 90 | }, 91 | "output":{ 92 | "type":"object", 93 | "required":["href","storage"], 94 | "properties":{ 95 | "href": { 96 | "type": "string", 97 | "minLength": 1 98 | }, 99 | "storage": { 100 | "type": "string", 101 | "enum": [ 102 | "external", 103 | "azure", 104 | "dropbox", 105 | "adobe" 106 | ], 107 | "default": "external" 108 | }, 109 | "overwrite": { 110 | "description": "If the file already exists, indicates if the output file should be overwritten. Only applies to files stored in Adobe storage.", 111 | "type": "boolean", 112 | "default": true 113 | }, 114 | "color": { 115 | "type":"object", 116 | "required":["space"], 117 | "properties":{ 118 | "space":{ 119 | "type":"string", 120 | "enum":["rgba","rgb"], 121 | "description": "Color space for the output image. Defaults to 'rgba for /cutout and 'rgb' for a /mask", 122 | "example": "rgb" 123 | } 124 | } 125 | }, 126 | "mask": { 127 | "type":"object", 128 | "required":["format"], 129 | "properties":{ 130 | "format":{ 131 | "type":"string", 132 | "enum":["soft","binary"], 133 | "default": "soft", 134 | "description": "A soft (feathered) mask or binary mask" 135 | } 136 | } 137 | } 138 | }, 139 | "if": { 140 | "properties": { 141 | "storage": { 142 | "pattern": "(^azure|external|dropbox$)", 143 | "description": "Asset stored on an external service (like AWS S3, Azure, Dropbox). If you are using presigned url for dropbox or azure, use `storage=\"dropbox\"` or `storage=\"azure\"` else it is `storage=\"external\"`" 144 | } 145 | } 146 | }, 147 | "then": { 148 | "properties": { 149 | "href": { 150 | "type": "string", 151 | "pattern": "^https://", 152 | "description": "Any public url or a presignedURL for the asset output" 153 | } 154 | } 155 | }, 156 | "else": { 157 | "properties": { 158 | "href": { 159 | "pattern": "^/?(temp|cloud-content|assets)/.+", 160 | "description": "A string representing the path to the output file stored on Adobe's cloud.
Not available for the integrations created with JWT authentication or Service Principle." 161 | }, 162 | "storage": { 163 | "description" : "Asset stored on Adobe's cloud.
Not available for the integrations created with JWT authentication or Service Principle." 164 | } 165 | } 166 | } 167 | } 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /static/PITS/file_input.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "file_input.schema.json", 4 | "title": "a file input obect", 5 | "description": "Represents the collective fields needed to indicate an input file", 6 | "definitions": { 7 | "href": { 8 | "type": "string", 9 | "minLength": 1, 10 | "example": "presignedURL" 11 | }, 12 | "storage": { 13 | "type": "string", 14 | "enum": [ 15 | "external", 16 | "azure", 17 | "dropbox", 18 | "adobe", 19 | "cclib" 20 | ], 21 | "default": "external" 22 | }, 23 | "actionName": { 24 | "description": "If you only want to execute a particular action, you may specify whcih action to play from the ActionSet", 25 | "type": "string" 26 | }, 27 | "input_objects_max_1": { 28 | "type": "array", 29 | "description": "An object describing an input file. Currently supported filetypes include:`jpeg`, `png`, `psd`, `tiff`", 30 | "maxItems": 1, 31 | "items": { 32 | "$ref": "#/definitions/input_object" 33 | } 34 | }, 35 | "input_objects_max_2": { 36 | "type": "array", 37 | "description": "An object describing an input file. Currently supported filetypes include:`jpeg`, `png`, `psd`, `tiff`. First input contains before image and second input contains after image", 38 | "minItems": 2, 39 | "maxItems": 2, 40 | "items": { 41 | "$ref": "#/definitions/input_object" 42 | } 43 | }, 44 | "input_objects": { 45 | "type": "array", 46 | "description": "An array of hashes describing the input files to edit. each input object will be either 'external', 'adobe', 'azure' or 'dropbox'", 47 | "items": { 48 | "$ref": "#/definitions/input_object" 49 | } 50 | }, 51 | "input_objects_action": { 52 | "type": "array", 53 | "description": "An array of hashes describing the input action files to edit. each input object will be either 'external', 'adobe', 'azure' or 'dropbox'", 54 | "items": { 55 | "$ref": "#/definitions/input_object_action" 56 | } 57 | }, 58 | "artboard_objects": { 59 | "type": "array", 60 | "minLength": 1, 61 | "description": "An array of hashes describing the input files to edit. each input object will be either 'external', 'adobe', 'azure' or 'dropbox'", 62 | "items": { 63 | "$ref": "#/definitions/input_object" 64 | } 65 | }, 66 | "input_object": { 67 | "type": "object", 68 | "minProperties": 1, 69 | "description": "An object describing an input file. Currently supported filetypes include:`jpeg`, `png`, `psd`, `tiff`", 70 | "required": [ 71 | "href", 72 | "storage" 73 | ], 74 | "properties": { 75 | "storage": { 76 | "$ref": "#/definitions/storage" 77 | }, 78 | "href": { 79 | "$ref": "#/definitions/href" 80 | } 81 | }, 82 | "if": { 83 | "properties": { 84 | "storage": { 85 | "pattern": "(^azure|external|dropbox$)", 86 | "description": "Asset stored on an external service (like AWS S3, Azure, Dropbox). If you are using presigned url for dropbox or azure, use `storage=\"dropbox\"` or `storage=\"azure\"` else it is `storage=\"external\"`" 87 | } 88 | } 89 | }, 90 | "then": { 91 | "properties": { 92 | "href": { 93 | "type": "string", 94 | "pattern": "^https://", 95 | "description": "Any public url or a presignedURL for the asset input" 96 | } 97 | } 98 | }, 99 | "else": { 100 | "if" : { 101 | "properties": { 102 | "storage": { 103 | "pattern": "(^cclib$)" 104 | } 105 | } 106 | }, 107 | "then" : { 108 | "properties": { 109 | "href": { 110 | "pattern": "^/?(api)/.+", 111 | "description": "A string representing the path to the input CC Libraries file" 112 | }, 113 | "storage": { 114 | "description" : "Asset stored on Adobe's cclib `cclib`.
Not available for the integrations created with JWT authentication or Service Principle." 115 | } 116 | } 117 | }, 118 | "else" : { 119 | "properties": { 120 | "href": { 121 | "pattern": "^/?(temp|cloud-content|assets|pubs)/.+", 122 | "description": "A string representing the path to the input CC Storage file.
Not available for the integrations created with JWT authentication or Service Principle." 123 | }, 124 | "storage": { 125 | "description" : "Asset stored on Adobe's cloud `adobe`.
Not available for the integrations created with JWT authentication or Service Principle." 126 | } 127 | } 128 | } 129 | } 130 | }, 131 | "input_object_action": { 132 | "type": "object", 133 | "minProperties": 1, 134 | "description": "An input action file to play. The input object will be either 'external', 'adobe', 'azure' or 'dropbox'", 135 | "required": [ 136 | "href", 137 | "storage" 138 | ], 139 | "properties": { 140 | "storage": { 141 | "$ref": "#/definitions/storage" 142 | }, 143 | "href": { 144 | "$ref": "#/definitions/href" 145 | }, 146 | "actionName": { 147 | "$ref": "#/definitions/actionName" 148 | } 149 | }, 150 | "if": { 151 | "properties": { 152 | "storage": { 153 | "pattern": "(^azure|external|dropbox$)" 154 | } 155 | } 156 | }, 157 | "then": { 158 | "properties": { 159 | "href": { 160 | "format": "uri", 161 | "pattern": "^https://", 162 | "description": "A URI representing the path to the input action file" 163 | } 164 | } 165 | }, 166 | "else": { 167 | "properties": { 168 | "href": { 169 | "pattern": "^/?(temp|cloud-content|assets|pubs)/.+", 170 | "description": "A string representing the path to the input CC file" 171 | } 172 | } 173 | } 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /sample-code/azure-blob-text-edit/app.js: -------------------------------------------------------------------------------- 1 | const storage = require("@azure/storage-blob") 2 | const fs = require("fs") 3 | const request = require('request') 4 | const endpoint = "https://image.adobe.io/pie/psdService/text" 5 | 6 | /**********************************************************************/ 7 | /**********************************************************************/ 8 | /*************** FILL IN THE FOLLOWING INFORMATION **********************/ 9 | /**********************************************************************/ 10 | /**********************************************************************/ 11 | // FILL OUT INFORMATION ABOUT YOUR ADOBE CREDENTIALS 12 | // VISIT https://developer.adobe.com/console/projects to obtain the following information 13 | const imsConfig = { 14 | clientId: "YOUR_ADOBE_CLIENT_ID", 15 | clientSecret: "YOUR_ADOBE_CLIENT_SECRET", 16 | }; 17 | 18 | // FILL OUT INFORMATION ABOUT YOUR AZURE BLOB STORAGE 19 | const azureStorageAccountName = "YOUR_AZURE_STORAGE_ACCOUNT_NAME"; 20 | const azureAccountAccessKey = "YOUR_AZURE_ACCOUNT_ACCESS_KEY" 21 | const azureInputPath = "PATH/TO/INPUT/FILE/IN/YOUR/AZURE/account.psd"; 22 | const azureOutputPath = "PATH/TO/WHERE/YOUR/WANT/THE/output.jpg"; 23 | const azureContainerName= "YOUR_AZURE_COTAINER_NAME"; 24 | 25 | // FILL OUT INFORMATION ABOUT THE PSD AND TEXTLAYER 26 | const textLayerName = "NAME_OF_THE_LAYER"; 27 | const textLayerContent = "YOUR_CONTENT"; 28 | 29 | /**********************************************************************/ 30 | /**********************************************************************/ 31 | /**********************************************************************/ 32 | 33 | async function generateIMSToken() { 34 | const url = 'https://ims-na1.adobelogin.com/ims/token/v3'; 35 | const options = { 36 | method: 'POST', 37 | url: url, 38 | headers: { 39 | 'Content-Type': 'application/x-www-form-urlencoded' 40 | }, 41 | form: { 42 | grant_type: 'client_credentials', 43 | client_id: imsConfig.clientId, 44 | client_secret: imsConfig.clientSecret, 45 | scope: 'openid,AdobeID,read_organizations' 46 | } 47 | }; 48 | 49 | return new Promise((resolve, reject) => { 50 | request(options, (err, res, body) => { 51 | if(err || res.statusCode >= 400) { 52 | reject( err || body ) 53 | }else{ 54 | resolve( body ) 55 | } 56 | }) 57 | }) 58 | } 59 | 60 | async function generateSASUrl(accountname, key, containerName, blobName){ 61 | const cerds = new storage.StorageSharedKeyCredential(accountname,key); 62 | const blobServiceClient = new storage.BlobServiceClient(`https://${accountname}.blob.core.windows.net`,cerds); 63 | const client =blobServiceClient.getContainerClient(containerName) 64 | const blobClient = client.getBlobClient(blobName); 65 | 66 | const blobSAS = storage.generateBlobSASQueryParameters({ 67 | containerName, 68 | blobName, 69 | permissions: storage.BlobSASPermissions.parse("racwd"), 70 | startsOn: new Date(), 71 | expiresOn: new Date(new Date().valueOf() + 86400) 72 | }, 73 | cerds 74 | ).toString(); 75 | 76 | const sasUrl= blobClient.url+"?"+blobSAS; 77 | return sasUrl; 78 | } 79 | 80 | async function postPhotoshopAPI(endpoint, apiKey, token, requestBody){ 81 | let options = { 82 | url: endpoint, 83 | method: 'POST', 84 | headers: { 85 | "Authorization": `Bearer ${token}`, 86 | "x-api-key": apiKey 87 | }, 88 | json: true, 89 | body: requestBody 90 | } 91 | return new Promise((resolve, reject) => { 92 | request(options, (err, res, body) => { 93 | if(err || res.statusCode >= 400) { 94 | reject( err || body ) 95 | }else{ 96 | resolve( body ) 97 | } 98 | }) 99 | }) 100 | } 101 | 102 | async function pollStatus(responseBody, apiKey, token){ 103 | let options = { 104 | url: responseBody._links.self.href, 105 | method: 'GET', 106 | headers: { 107 | "Authorization": `Bearer ${token}`, 108 | "x-api-key": apiKey 109 | }, 110 | json: true 111 | } 112 | 113 | return new Promise((resolve, reject) => { 114 | let pollFunction = () => { 115 | request(options, (err, res, body) => { 116 | console.log(body.jobId, body.outputs[0].status) 117 | if(err || res.statusCode >= 400) { 118 | clearInterval(intervalId) 119 | reject(err || res.statusCode) 120 | }else if(body.outputs[0].status == 'succeeded' || body.outputs[0].status == 'failed'){ 121 | clearInterval(intervalId) 122 | resolve( body ) 123 | } 124 | }) 125 | } 126 | let intervalId = setInterval(pollFunction, 1000) 127 | }) 128 | } 129 | 130 | 131 | async function main(){ 132 | let authDetails = await generateIMSToken(); 133 | let creds = JSON.parse(authDetails); 134 | let inputSASUrl = await generateSASUrl(azureStorageAccountName, azureAccountAccessKey, azureContainerName, azureInputPath) 135 | let outputSASUrl = await generateSASUrl(azureStorageAccountName, azureAccountAccessKey, azureContainerName, azureOutputPath) 136 | 137 | let requestBody = { 138 | "inputs":[ 139 | { 140 | "href": inputSASUrl, 141 | "storage": "azure" 142 | } 143 | ], 144 | "options":{ 145 | "layers":[ 146 | { 147 | "name": textLayerName, 148 | "text": { 149 | "content": textLayerContent, 150 | "orientation": "horizontal", 151 | "characterStyles": [{ 152 | "size": 15, 153 | "color": { 154 | "red":255, 155 | "green":0, 156 | "blue":0 157 | } 158 | }], 159 | "paragraphStyles": [{ 160 | "alignment": "right" 161 | }] 162 | } 163 | } 164 | ] 165 | }, 166 | "outputs":[ 167 | { 168 | "href": outputSASUrl, 169 | "storage": "azure", 170 | "type": "image/jpeg" 171 | } 172 | ] 173 | } 174 | 175 | try{ 176 | let response = await postPhotoshopAPI(endpoint, imsConfig.clientId, creds.access_token, requestBody) 177 | let status = await pollStatus(response, imsConfig.clientId, creds.access_token) 178 | console.log(JSON.stringify(status, null, 2)) 179 | }catch(e){ 180 | console.error(e) 181 | } 182 | 183 | } 184 | 185 | main(); 186 | -------------------------------------------------------------------------------- /static/PITS/post_action_json.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "post_action_json.schema.json", 4 | "title": "post_action_json", 5 | "description": "Initiates an asynchronous job to play Photoshop Action JSON", 6 | "type": "object", 7 | "required": [ 8 | "inputs", 9 | "options", 10 | "outputs" 11 | ], 12 | "properties": { 13 | "inputs": { 14 | "$ref": "file_input.schema.json#/definitions/input_objects_max_1" 15 | }, 16 | "options": { 17 | "type": "object", 18 | "required": ["actionJSON"], 19 | "properties": { 20 | "actionJSON": { 21 | "type": "array", 22 | "description": "An array of photoshop actions created as actionJSON to execute.", 23 | "minItems": 1, 24 | "items": { 25 | "description": "Each item contains an object with photoshop action" 26 | } 27 | }, 28 | "fonts": { 29 | "$ref": "file_input.schema.json#/definitions/input_objects", 30 | "description": "An array of font objects you wish use when executing the action." 31 | }, 32 | "patterns": { 33 | "type": "array", 34 | "description": "A pattern object which tells the API where to download the pattern file that is needed for your action", 35 | "minItems": 1, 36 | "items": { 37 | "required": [ 38 | "href", 39 | "storage" 40 | ], 41 | "properties": { 42 | "storage": { 43 | "$ref": "file_input.schema.json#/definitions/storage" 44 | }, 45 | "href": { 46 | "$ref": "file_input.schema.json#/definitions/href" 47 | } 48 | }, 49 | "if": { 50 | "properties": { 51 | "storage": { 52 | "pattern": "(^azure|external|dropbox$)" 53 | } 54 | } 55 | }, 56 | "then": { 57 | "properties": { 58 | "href": { 59 | "format": "uri", 60 | "pattern": "^https://", 61 | "description": "A URI representing the path to the input file" 62 | } 63 | } 64 | }, 65 | "else": { 66 | "if": { 67 | "properties": { 68 | "storage": { 69 | "pattern": "(^cclib$)" 70 | } 71 | } 72 | }, 73 | "then": { 74 | "properties": { 75 | "href": { 76 | "pattern": "^/?(api)/.+", 77 | "description": "A string representing the path to the input CC Libraries file" 78 | } 79 | } 80 | }, 81 | "else": { 82 | "properties": { 83 | "href": { 84 | "pattern": "^/?(temp|cloud-content|assets|pubs)/.+", 85 | "description": "A string representing the path to the input CC Storage file" 86 | } 87 | } 88 | } 89 | } 90 | } 91 | }, 92 | "brushes": { 93 | "type": "array", 94 | "description": "A brush object which tells the API where to download the pattern file that is needed for your action", 95 | "minItems": 1, 96 | "items": { 97 | "required": [ 98 | "href", 99 | "storage" 100 | ], 101 | "properties": { 102 | "storage": { 103 | "$ref": "file_input.schema.json#/definitions/storage" 104 | }, 105 | "href": { 106 | "$ref": "file_input.schema.json#/definitions/href" 107 | } 108 | }, 109 | "if": { 110 | "properties": { 111 | "storage": { 112 | "pattern": "(^azure|external|dropbox$)" 113 | } 114 | } 115 | }, 116 | "then": { 117 | "properties": { 118 | "href": { 119 | "format": "uri", 120 | "pattern": "^https://", 121 | "description": "A URI representing the path to the input file" 122 | } 123 | } 124 | }, 125 | "else": { 126 | "if": { 127 | "properties": { 128 | "storage": { 129 | "pattern": "(^cclib$)" 130 | } 131 | } 132 | }, 133 | "then": { 134 | "properties": { 135 | "href": { 136 | "pattern": "^/?(api)/.+", 137 | "description": "A string representing the path to the input CC Libraries file" 138 | } 139 | } 140 | }, 141 | "else": { 142 | "properties": { 143 | "href": { 144 | "pattern": "^/?(temp|cloud-content|assets|pubs)/.+", 145 | "description": "A string representing the path to the input CC Storage file" 146 | } 147 | } 148 | } 149 | } 150 | } 151 | }, 152 | "additionalImages": { 153 | "type": "array", 154 | "description": "Image objects which tells the API where to download additional images that is needed for your action. Currently, the only allowed placeholder within your is ACTION_JSON_OPTIONS_ADDITIONAL_IMAGES_X where X is the index of the additionalImages array", 155 | "minItems": 1, 156 | "items": { 157 | "required": [ 158 | "href", 159 | "storage" 160 | ], 161 | "properties": { 162 | "storage": { 163 | "$ref": "file_input.schema.json#/definitions/storage" 164 | }, 165 | "href": { 166 | "$ref": "file_input.schema.json#/definitions/href" 167 | } 168 | }, 169 | "if": { 170 | "properties": { 171 | "storage": { 172 | "pattern": "(^azure|external|dropbox$)" 173 | } 174 | } 175 | }, 176 | "then": { 177 | "properties": { 178 | "href": { 179 | "format": "uri", 180 | "pattern": "^https://", 181 | "description": "A URI representing the path to the input file" 182 | } 183 | } 184 | }, 185 | "else": { 186 | "if": { 187 | "properties": { 188 | "storage": { 189 | "pattern": "(^cclib$)" 190 | } 191 | } 192 | }, 193 | "then": { 194 | "properties": { 195 | "href": { 196 | "pattern": "^/?(api)/.+", 197 | "description": "A string representing the path to the input CC Libraries file" 198 | } 199 | } 200 | }, 201 | "else": { 202 | "properties": { 203 | "href": { 204 | "pattern": "^/?(temp|cloud-content|assets|pubs)/.+", 205 | "description": "A string representing the path to the input CC Storage file" 206 | } 207 | } 208 | } 209 | } 210 | } 211 | } 212 | } 213 | }, 214 | "outputs": { 215 | "$ref": "file_output_pegasus.schema.json#/definitions/output_objects" 216 | } 217 | } 218 | } 219 | --------------------------------------------------------------------------------