Skip to content

Repository files navigation

Unofficial Frontify Python SDK

Not officially endorsed or supported by Frontify.

Bootstrapped with gql-generator to programatically create queries and mutations from a schema, and ariadne-codegen.

The goal is to eventually publish this as a PyPI package, but it works just fine imported as a module for now.

Usage

Local package installation (optional)

To install the package in your environment, you can run python setup.py install and then pip install frontify which will allow you to use it as a regular import instead of importing the entire module.

Client

Import and initialise the client as follows:

importosfromfrontify.asyncFrontifyClientimportAsyncFrontifyClientasFrontifyClientfrontify_access_token=os.getenv('frontify_access_token')
frontifyHeaders= {'Authorization': f"Bearer {frontify_access_token}",
'Content-Type': 'application/json',
'X-Frontify-Beta': 'enabled'}
frontifyClient=FrontifyClient(url='https://demo.frontify.com/graphql', headers=frontifyHeaders)

NB: The generated client is asyncronous by default, and while better for performance, it will mean that the way of working is different to the client exemplified in the Frontify API Example repository.

All examples will follow the usage of the async client, but a synchronous client is also available.

Importing types

Import input types from frontify.input_types to use them for easier creation of query and mutation inputs, for example:

fromfrontify.input_typesimportCreateAssetInput, UploadFileInputuploadFileInput=UploadFileInput(
filename='test.jpg',
size=1000
)
createAssetInput=CreateAssetInput(
fileId=fileId,
title='test',
description='test',
projectId='ey...[REDACTED]',
)

Using a predefined query

Anything listed as a query in the GraphQL Reference can be accessed directly through the client. For example, to query an account:

accountResponse=asyncio.run(frontifyClient.account())
print("Account ID: ", accountResponse.account.id)

or to query brands by ID:

brandResponse=asyncio.run(frontifyClient.brand(id=1234))
print(brandResponse.brand.id)

Note the use of asyncio.run() as these functions are asynchronous and must be awaited.

Alternatively, you can run mutiple queries asynchronously as shown:

asyncdefmain(client: FrontifyClient):
# Await the account queryresponse=awaitclient.account()
# Access the response dataprint("Account ID: ", response.account.id)
# Await the brand queryresponse=awaitclient.brand(1234)
# Access the response dataprint("Brand ID: ", response.brand.id)
# Run the async functionasyncio.run(main(frontifyClient))

Using a predefined mutation

Mutations can accessed in a very similar way from the client class. For example, an asset upload may look something like this:

asyncdefuploadFile(uploadFileInput: UploadFileInput, file_path: str):
uploadFileResponse=awaitfrontifyClient.uploadFile(uploadFileInput)
fileId=uploadFileResponse.upload_file.idurls=uploadFileResponse.upload_file.urlsforurlinurls:
uploadChunk(url)
createAssetInput=CreateAssetInput(
fileId=fileId,
title='test',
description='test',
projectId='ey...[REDACTED]',
)
returnawaitfrontifyClient.create_asset(createAssetInput)
asyncio.run(uploadFile(uploadFileInput, 'test.jpg'))

Execute a custom query

If none of the generated queries work or more depth is required, a custom query can be executed as shown in this example for custom metadata fields:

custom_query="""query LibraryMetadataFields($libraryId: ID!) { library(id: $libraryId) { customMetadataProperties { ... on CustomMetadataProperty { id name type { ... on CustomMetadataPropertyType { name ... on CustomMetadataPropertyTypeSelect { options { id value } } ... on CustomMetadataPropertyTypeMultiSelect{ options { id value } } } } } } }}"""# Variables for the queryvariables= {"libraryId": 18690}
# Execute the custom queryresponse=asyncio.run(frontifyClient.execute(custom_query, variables=variables))
data=frontifyClient.get_data(response)
print(data)

Notes on synchronous usage

If using FrontifyClient it is not necessary to utilise asyncio and queries/mutations can be made without awaiting, for example:

Import

importosfromdotenvimportload_dotenvfromfrontify.frontifyClientimportFrontifyClientload_dotenv(verbose=True, override=True)
frontify_access_token=os.getenv('frontify_access_token')
frontifyHeaders= {'Authorization': f"Bearer {frontify_access_token}",
'Content-Type': 'application/json',
'X-Frontify-Beta': 'enabled'}
frontifyClient=FrontifyClient(url='https://demo.frontify.com/graphql', headers=frontifyHeaders)

Simple query

accountResponse=frontifyClient.account()
print("Account ID: ", accountResponse.account.id)

Custom query

# Define a custom query as a stringcustom_query="""query LibraryMetadataFields($libraryId: ID!) { library(id: $libraryId) { customMetadataProperties { ... on CustomMetadataProperty { id name type { ... on CustomMetadataPropertyType { name ... on CustomMetadataPropertyTypeSelect { options { id value } } ... on CustomMetadataPropertyTypeMultiSelect{ options { id value } } } } } } }}"""# Variables for the queryvariables= {"libraryId": 18690}
# Execute the custom queryresponse=frontifyClient.execute(custom_query, variables=variables)
data=frontifyClient.get_data(response)
print(data)

Mutation

fromfrontify.input_typesimportDeleteAssetInputdeleteAssetInput=DeleteAssetInput(id="12345")
# NB the ID can also be a base64 encoded ID, but must be a string per type rulesdeleteResponse=frontifyClient.delete_asset(deleteAssetInput)
print("Delete asset ID: ", deleteResponse.delete_asset.id)

About

A quick and dirty Python SDK for Frontify

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages