Skip to content

mmnitzsche/powerquery_api_integration

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 

Repository files navigation

🎬 Studio Tracker - Integração de API's: ClickUp + Frame.io + Power BI

  Studio Tracker - Integração de APIs

  Studio Tracker - Integração de APIs

⚡ Visão Geral do Projeto

Este projeto apresenta uma solução completa e escalável para integração de dados entre ClickUp (gestão de tarefas), Frame.io (revisão de vídeos) e Power BI (Business Intelligence).

Com o uso do Power Query (M Language) para consumir diretamente as APIs REST dessas plataformas, o Studio Tracker automatiza a coleta, transformação e consolidação de informações — eliminando processos manuais, planilhas complexas ou infraestruturas de ETL e scripts fragmentados.

⚠️ Observação: O uso das APIs das plataformas neste projeto serve apenas como exemplo prático de integração via Power Query. O foco é demonstrar técnicas de consumo de APIs paginadas e a consolidação de múltiplas fontes em um único dashboard de BI.

No exemplo só vou me ater a utulizar a API do ClickUp já que o método é identico o que muda só é a variáveis de negócio de cada API

Tecnologias utilizadas

  Studio Tracker - Integração de APIs

Estrutura do Projeto

├─ 📁 assets
│  └─ 📁 assignee               # Avatar dos usuários
│
└─ 📁 env                       # Credenciais
   ├─ 📄 clickup_token.txt
   └─ 📄 frameio_token.txt
│
├─ 📁 power_bi_file             # Arquivo .pbix
   └─ 📊 Animation Studio.pbix

🔗 Acesso e Documentação

Recurso Descrição
Dashboard Interativo Acesse o resultado final da integração no Power BI: Dashboard
Artigo Detalhado Saiba mais sobre o contexto do projeto e sua trajetória: Artigo

1. Clonar o Repositório

Baixe ou clone este repositório para sua máquina local:

git clone https://github.com/mmnitzsche/powerquery_api_integration

2. Configuração de Tokens na Pasta env

A pasta env armazena os tokens de autenticação necessários. Crie dois arquivos de texto exatamente com os nomes abaixo dentro da pasta env, e cole seu token API em cada um:

Arquivo Conteúdo Documentação API
env/clickup_token.txt Seu Personal API Token do ClickUp Documentação ClickUp API
env/frameio_token.txt Seu Developer Token do Frame.io Documentação Frame.io API

Importante: Esses arquivos estão listados no .gitignore para garantir que suas credenciais não sejam expostas publicamente.


3. Requisições via Power Query

Esta seção demonstra como o Power Query é usado para consumir e transformar dados do ClickUp, oferecendo uma alternativa barata dentro do possível da solução desejada.

Por que usar Power Query para APIs?

Embora scripts em Python ofereçam maior flexibilidade e possibilidades avançadas de manipulação de dados, exigem bibliotecas externas (requests, pandas) e um ambiente de execução dedicado. O Power Query, por outro lado, permite conectar-se diretamente a APIs REST, transformar e consolidar dados de forma visual e automatizada, servindo como uma alternativa prática e escalável que pode substituir parte da infraestrutura mais complexa necessária em soluções baseadas apenas em código.

  • Conexão Nativa: Conecta-se diretamente a APIs REST com autenticação e cabeçalhos integrados.
  • Transformação Visual: Expande e renomeia campos JSON de forma intuitiva.
  • Automação Completa: Atualiza dados automaticamente no Power BI sem necessidade de código adicional.

Exemplo Básico – Autenticação

Abaixo vamos começar a entrar no passo a passo e ver como funciona requisições do tipo GET no Power Query.

clickup_token = 
    let
        Source = Table.FromColumns({Lines.FromBinary(File.Contents("C:\Users\Mateus\Documents\Blog\Animation Studio\env\clickup_token.txt"), null, null, 1252)}),
        #"Renamed Columns" = Table.RenameColumns(Source,{{"Column1", "token"}})
    in
        #"Renamed Columns",

// Cabeçalho da requisição
headers = [
    #"accept" = "application/json",
    #"Authorization" = clickup_token{0}[token]
]

Equivalente em Python:

import requests
token = "SEU_TOKEN"
headers = {"Authorization": token}
response = requests.get("https://api.clickup.com/api/v2/team", headers=headers)
data = response.json()

3.2. Requisições Múltiplas

A seguir, funções que consultam diferentes endpoints para obter teams, spaces e lists — necessárias antes de buscar as tasks:

// Função para obter os teams
getTeams = (team_name as text) as record =>
    let
        response = Json.Document(Web.Contents("https://api.clickup.com", [RelativePath="api/v2/team", Headers=headers])),
        teams = response[teams],
        dfTeams = Table.FromRecords(teams),
        team_id = Record.Field(List.First(List.Select(teams, each _[name] = team_name)), "id")
    in
        [df=dfTeams, id=team_id],

// Função para obter os spaces
getSpaces = (team_id as text, space_name as text) as record =>
    let
        response = Json.Document(Web.Contents("https://api.clickup.com", [RelativePath="api/v2/team/" & team_id & "/space", Headers=headers])),
        spaces = response[spaces],
        dfSpaces = Table.FromRecords(spaces),
        space_id = Record.Field(List.First(List.Select(spaces, each _[name] = space_name)), "id")
    in
        [df=dfSpaces, id=space_id],

// Função para obter as listas
getLists = (space_id as text) as record =>
    let
        response = Json.Document(Web.Contents("https://api.clickup.com", [RelativePath="api/v2/space/" & space_id & "/list", Headers=headers])),
        lists = response[lists],
        dfLists = Table.FromRecords(lists),
        list_id = Record.Field(List.First(List.Select(lists, each _[name] = "Scenes")), "id")
    in
        [df=dfLists, id=list_id]

3.3. Requisição principal – Endpoint /list

O endpoint /list é o mais importante, pois fornece a base de dados principal usada no dashboard.

getAllTasks = (list_id as text) as table =>
    let
        GetTasksPerPage = (page as number) as list =>
            let
                response = Json.Document(Web.Contents("https://api.clickup.com", [RelativePath="api/v2/list/" & list_id & "/task", Query=[page=Number.ToText(page), include_closed="true"], Headers=headers])),
                tasks = try response[tasks] otherwise {}
            in
                tasks,

        FetchAllTasks = List.Generate(
            () => [page = 0, tasks = GetTasksPerPage(0)],
            each List.Count([tasks]) > 0,
            each [page = [page] + 1, tasks = GetTasksPerPage([page])],
            each [tasks]
        ),

        allTasks = List.Combine(FetchAllTasks),
        dfTasks = Table.FromRecords(allTasks)
    in
        dfTasks

Exemplo de resposta JSON:

{
  "id": "86a6x2gxf",
  "name": "NITIT_004_009",
  "Status": "Open",
  "status.id": "sc901307541828_fdONRjp8",
  "status.color": "#87909e",
  "creator.username": "Mateus Nitzsche",
  "creator.email": "mmnitzsche@gmail.com",
  "date_created": 1740374812732,
  "date_updated": 1740599141056,
  "index": 1,
  "url": "https://app.clickup.com/t/86a6x2gxf"
}
id name Status status.id status.color creator.username creator.email date_created date_updated index url
86a6x2gxf NITIT_004_009 Open sc901307541828_fdONRjp8 #87909e Mateus Nitzsche mmnitzsche@gmail.com 1740374812732 1740599141056 1 https://app.clickup.com/t/86a6x2gxf

4. Técnicas e Manipulação de Dados

  • Requisição por página (GetTasksPerPage) → Busca tasks por página e retorna lista vazia caso não haja resultados.
  • Iteração declarativa (List.Generate) → Cria sequência de páginas enquanto houver tasks, sem loops manuais.
  • Combinação de resultados (List.Combine) → Consolida as listas de páginas em uma única lista completa.
  • Transformação final (Table.FromRecords) → Converte JSON em tabela, permitindo expandir colunas, renomear campos e adicionar índices.

Em Python, o mesmo processo exigiria um loop while com requests.get(). No Power Query, tudo é declarativo — definido por estado inicial, condição de continuação e valor retornado.

5. Integração entre as duas fontes de dados

Após coletar os dados das duas fontes (ClickUp e Frame.io), é essencial criar uma camada de negócios para identificar os pontos em comum entre elas. No contexto deste projeto, os dois campos que serviram de chave de integração foram o nome da tarefa e o nome do arquivo de vídeo, que possuem valores equivalentes. Foi necessário apenas um pequeno tratamento nos dados do Frame.io, já que os nomes dos arquivos incluem a extensão .mp4 (ex.: NITIT_004_009.mp4), permitindo a consolidação correta das informações. '

Studio Tracker - Integração de APIs

6. Considerações finais

Recurso Descrição
Portifólio Confira mais conteúdos sobre dados, BI e projetos : bit.ly/mateusnit
Dashboard Interativo Acesse o resultado final da integração no Power BI: Dashboard
Artigo Detalhado Saiba mais sobre o contexto do projeto e sua trajetória: Artigo

About

Projeto de integração e automação que conecta plataformas de gestão e revisão de conteúdo em um dashboard interativo. Aumenta a produtividade em mais de 100%, eliminando processos manuais, consolidando dados de tarefas e vídeos, e oferecendo insights acionáveis para empresas que buscam eficiência e visibilidade total.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors