Normalizing Nested JSON in python

Question:

I’m really new to API’S and python so,

I’m trying to convert a API request JSON that contains nested data into a pandas DataFrame to input it in power BI as a external python file, but I can’t figure out what’s hapennig with my JSON normalizing. It is a paginate API, so i had to implement a loop to get all data from it. I was expecting after runnig my code, a beautiful dataframe just to import on Power BI, can anyone help me?

the request API JSON be like

"retorno": {
        "produtos": [
            {
                "produto": {
                    "id": "15874512815",
                    "codigo": "005.02.G",
                    "descricao": "CALÇA NATUREZA  OFF WHITE TAMANHO G",
                    "tipo": "P",
                    "situacao": "Ativo",
                    "unidade": "UN",
                    "preco": "172.9000000000",
                    "precoCusto": null,
                    "descricaoCurta": "<p style="box-sizing: border-box; padding: 0px; border: 0px; outline: none; margin-block: 0px 1em; color: #333333; font-family: Lato, sans-serif; font-size: 18px; background-color: #fefffe;"><span style="box-sizing: border-box; padding: 0px; margin: 0px; border: 0px; outline: none; font-size: 12px;"><span style="box-sizing: border-box; padding: 0px; margin: 0px; border: 0px; outline: none; font-family: Tahoma, Geneva, sans-serif;">Aquela calça super comfy e estilosa para te acompanhar nesse inverno!</span></span></p>n<p style="box-sizing: border-box; padding: 0px; border: 0px; outline: none; margin-block: 0px; color: #333333; font-family: Lato, sans-serif; font-size: 18px; background-color: #fefffe;"><span style="box-sizing: border-box; padding: 0px; margin: 0px; border: 0px; outline: none; font-size: 12px;"><span style="box-sizing: border-box; padding: 0px; margin: 0px; border: 0px; outline: none; font-family: Tahoma, Geneva, sans-serif;">Com moletom felpado e uma modelagem que abraça o corpo, ela é a nossa queridinha por aqui! &lt;3</span></span></p>",
                    "descricaoComplementar": "",
                    "dataInclusao": "2022-05-26",
                    "dataAlteracao": "2022-11-08",
                    "imageThumbnail": "http://orgbling.s3.amazonaws.com/358dd3a99dc65df69a3f3852c88a9c7f/t/ff947f17eb154298f3fb991594ab17b2?AWSAccessKeyId=AKIATCLMSGFX4J7TU445&Expires=1669817234&Signature=PPHn8S%2FTDDIGI0nKS3dYXXwfLR4%3D",
                    "urlVideo": "",
                    "nomeFornecedor": "",
                    "codigoFabricante": "",
                    "marca": "",
                    "class_fiscal": "6006.32.20",
                    "cest": "",
                    "origem": "0",
                    "idGrupoProduto": "0",
                    "linkExterno": "",
                    "observacoes": "",
                    "grupoProduto": null,
                    "garantia": null,
                    "descricaoFornecedor": null,
                    "idFabricante": "",
                    "categoria": {
                        "id": "5108713",
                        "descricao": "Calças"
                    },
                    "pesoLiq": "0.30000",
                    "pesoBruto": "0.31000",
                    "estoqueMinimo": "0.00",
                    "estoqueMaximo": "0.00",
                    "gtin": "",
                    "gtinEmbalagem": "",
                    "larguraProduto": "1",
                    "alturaProduto": "1",
                    "profundidadeProduto": "1",
                    "unidadeMedida": "Centímetros",
                    "itensPorCaixa": 0,
                    "volumes": 0,
                    "localizacao": "",
                    "crossdocking": "0",
                    "condicao": "Não Especificado",
                    "freteGratis": "N",
                    "producao": "P",
                    "dataValidade": "0000-00-00",
                    "spedTipoItem": "",
                    "clonarDadosPai": "S",
                    "codigoPai": "005.02"
                }
            },
            {
                "produto": {
                    "id": "15874512814",
                    "codigo": "005.02.M",
                    "descricao": "CALÇA NATUREZA  OFF WHITE TAMANHO M",
                    "tipo": "P",
                    "situacao": "Ativo",
                    "unidade": "UN",
                    "preco": "172.9000000000",
                    "precoCusto": null,
                    "descricaoCurta": "<p style="box-sizing: border-box; padding: 0px; border: 0px; outline: none; margin-block: 0px 1em; color: #333333; font-family: Lato, sans-serif; font-size: 18px; background-color: #fefffe;"><span style="box-sizing: border-box; padding: 0px; margin: 0px; border: 0px; outline: none; font-size: 12px;"><span style="box-sizing: border-box; padding: 0px; margin: 0px; border: 0px; outline: none; font-family: Tahoma, Geneva, sans-serif;">Aquela calça super comfy e estilosa para te acompanhar nesse inverno!</span></span></p>n<p style="box-sizing: border-box; padding: 0px; border: 0px; outline: none; margin-block: 0px; color: #333333; font-family: Lato, sans-serif; font-size: 18px; background-color: #fefffe;"><span style="box-sizing: border-box; padding: 0px; margin: 0px; border: 0px; outline: none; font-size: 12px;"><span style="box-sizing: border-box; padding: 0px; margin: 0px; border: 0px; outline: none; font-family: Tahoma, Geneva, sans-serif;">Com moletom felpado e uma modelagem que abraça o corpo, ela é a nossa queridinha por aqui! &lt;3</span></span></p>",
                    "descricaoComplementar": "",
                    "dataInclusao": "2022-05-26",
                    "dataAlteracao": "2022-11-08",
                    "imageThumbnail": "http://orgbling.s3.amazonaws.com/358dd3a99dc65df69a3f3852c88a9c7f/t/ff947f17eb154298f3fb991594ab17b2?AWSAccessKeyId=AKIATCLMSGFX4J7TU445&Expires=1669817234&Signature=PPHn8S%2FTDDIGI0nKS3dYXXwfLR4%3D",
                    "urlVideo": "",
                    "nomeFornecedor": "",
                    "codigoFabricante": "",
                    "marca": "",
                    "class_fiscal": "6006.32.20",
                    "cest": "",
                    "origem": "0",
                    "idGrupoProduto": "0",
                    "linkExterno": "",
                    "observacoes": "",
                    "grupoProduto": null,
                    "garantia": null,
                    "descricaoFornecedor": null,
                    "idFabricante": "",
                    "categoria": {
                        "id": "5108713",
                        "descricao": "Calças"
                    },
                    "pesoLiq": "0.30000",
                    "pesoBruto": "0.31000",
                    "estoqueMinimo": "0.00",
                    "estoqueMaximo": "0.00",
                    "gtin": "",
                    "gtinEmbalagem": "",
                    "larguraProduto": "1",
                    "alturaProduto": "1",
                    "profundidadeProduto": "1",
                    "unidadeMedida": "Centímetros",
                    "itensPorCaixa": 0,
                    "volumes": 0,
                    "localizacao": "",
                    "crossdocking": "0",
                    "condicao": "Não Especificado",
                    "freteGratis": "N",
                    "producao": "P",
                    "dataValidade": "0000-00-00",
                    "spedTipoItem": "",
                    "clonarDadosPai": "S",
                    "codigoPai": "005.02"
                }
            },

My code be like

import requests
import pandas as pd
from pandas import json_normalize
import json

BLING_SECRET_KEY = my_apikey

def list_products(page=1):
    url = f'https://bling.com.br/Api/v2/produtos/page={page}/json/'
    payload = {'apikey': BLING_SECRET_KEY,}
    all_products = {'retorno': {'produtos': []}}

    if page == 'all':
        page = 1
        
        while True:
            url = f'https://bling.com.br/Api/v2/produtos/page={page}/json/'
            produtos = requests.get(url, params=payload)
            try:
                pagina = produtos.json()['retorno']['produtos']
                page += 1
                for item in pagina:
                    all_products['retorno']['produtos'].append(item)
            except KeyError:

                break

            df = json_normalize(all_products, 
                                meta=['produtos'])
            print(df)   
  

produtos = list_products('all') 

With this code, I’m getting the follow result

                                    retorno.produtos
0  [{'produto': {'id': '15956635451', 'codigo': '...
                                    retorno.produtos
0  [{'produto': {'id': '15956635451', 'codigo': '...
                                    retorno.produtos
0  [{'produto': {'id': '15956635451', 'codigo': '...
                                    retorno.produtos
0  [{'produto': {'id': '15956635451', 'codigo': '...
                                    retorno.produtos
0  [{'produto': {'id': '15956635451', 'codigo': '...
                                    retorno.produtos
0  [{'produto': {'id': '15956635451', 'codigo': '...
                                    retorno.produtos
0  [{'produto': {'id': '15956635451', 'codigo': '...
                                    retorno.produtos
0  [{'produto': {'id': '15956635451', 'codigo': '...
                                    retorno.produtos
0  [{'produto': {'id': '15956635451', 'codigo': '...
Asked By: BI Dev

||

Answers:

if produtos = list_products(‘all’) is the output df in the question.

produtos = list_products('all')
df = pd.json_normalize(produtos.explode('retorno.produtos')['retorno.produtos'])

'''
|    |   produto.id | produto.codigo   | produto.descricao                   | produto.tipo   | produto.situacao   | produto.unidade   |   produto.preco |   produto.precoCusto | produto.descricaoCurta                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | produto.descricaoComplementar   | produto.dataInclusao   | produto.dataAlteracao   | produto.imageThumbnail                                                                                                                                                                                      | produto.urlVideo   | produto.nomeFornecedor   | produto.codigoFabricante   | produto.marca   | produto.class_fiscal   | produto.cest   |   produto.origem |   produto.idGrupoProduto | produto.linkExterno   | produto.observacoes   |   produto.grupoProduto |   produto.garantia |   produto.descricaoFornecedor | produto.idFabricante   |   produto.categoria.id | produto.categoria.descricao   |   produto.pesoLiq |   produto.pesoBruto |   produto.estoqueMinimo |   produto.estoqueMaximo | produto.gtin   | produto.gtinEmbalagem   |   produto.larguraProduto |   produto.alturaProduto |   produto.profundidadeProduto | produto.unidadeMedida   |   produto.itensPorCaixa |   produto.volumes | produto.localizacao   |   produto.crossdocking | produto.condicao   | produto.freteGratis   | produto.producao   | produto.dataValidade   | produto.spedTipoItem   | produto.clonarDadosPai   |   produto.codigoPai |
|---:|-------------:|:-----------------|:------------------------------------|:---------------|:-------------------|:------------------|----------------:|---------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------|:-----------------------|:------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------|:-------------------------|:---------------------------|:----------------|:-----------------------|:---------------|-----------------:|-------------------------:|:----------------------|:----------------------|-----------------------:|-------------------:|------------------------------:|:-----------------------|-----------------------:|:------------------------------|------------------:|--------------------:|------------------------:|------------------------:|:---------------|:------------------------|-------------------------:|------------------------:|------------------------------:|:------------------------|------------------------:|------------------:|:----------------------|-----------------------:|:-------------------|:----------------------|:-------------------|:-----------------------|:-----------------------|:-------------------------|--------------------:|
|  0 |  15874512815 | 005.02.G         | CALÇA NATUREZA  OFF WHITE TAMANHO G | P              | Ativo              | UN                |           172.9 |                  nan | <p style="box-sizing: border-box; padding: 0px; border: 0px; outline: none; margin-block: 0px 1em; color: #333333; font-family: Lato, sans-serif; font-size: 18px; background-color: #fefffe;"><span style="box-sizing: border-box; padding: 0px; margin: 0px; border: 0px; outline: none; font-size: 12px;"><span style="box-sizing: border-box; padding: 0px; margin: 0px; border: 0px; outline: none; font-family: Tahoma, Geneva, sans-serif;">Aquela calça super comfy e estilosa para te acompanhar nesse inverno!</span></span></p>                        |                                 | 2022-05-26             | 2022-11-08              | http://orgbling.s3.amazonaws.com/358dd3a99dc65df69a3f3852c88a9c7f/t/ff947f17eb154298f3fb991594ab17b2?AWSAccessKeyId=AKIATCLMSGFX4J7TU445&Expires=1669817234&Signature=PPHn8S%2FTDDIGI0nKS3dYXXwfLR4%3D |                    |                          |                            |                 | 6006.32.20             |                |                0 |                        0 |                       |                       |                    nan |                nan |                           nan |                        |                5108713 | Calças                        |               0.3 |                0.31 |                       0 |                       0 |                |                         |                        1 |                       1 |                             1 | Centímetros             |                       0 |                 0 |                       |                      0 | Não Especificado   | N                     | P                  | 0000-00-00             |                        | S                        |                5.02 |
|    |              |                  |                                     |                |                    |                   |                 |                      | <p style="box-sizing: border-box; padding: 0px; border: 0px; outline: none; margin-block: 0px; color: #333333; font-family: Lato, sans-serif; font-size: 18px; background-color: #fefffe;"><span style="box-sizing: border-box; padding: 0px; margin: 0px; border: 0px; outline: none; font-size: 12px;"><span style="box-sizing: border-box; padding: 0px; margin: 0px; border: 0px; outline: none; font-family: Tahoma, Geneva, sans-serif;">Com moletom felpado e uma modelagem que abraça o corpo, ela é a nossa queridinha por aqui! &lt;3</span></span></p> |                                 |                        |                         |                                                                                                                                                                                                             |                    |                          |                            |                 |                        |                |                  |                          |                       |                       |                        |                    |                               |                        |                        |                               |                   |                     |                         |                         |                |                         |                          |                         |                               |                         |                         |                   |                       |                        |                    |                       |                    |                        |                        |                          |                     |
|  1 |  15874512814 | 005.02.M         | CALÇA NATUREZA  OFF WHITE TAMANHO M | P              | Ativo              | UN                |           172.9 |                  nan | <p style="box-sizing: border-box; padding: 0px; border: 0px; outline: none; margin-block: 0px 1em; color: #333333; font-family: Lato, sans-serif; font-size: 18px; background-color: #fefffe;"><span style="box-sizing: border-box; padding: 0px; margin: 0px; border: 0px; outline: none; font-size: 12px;"><span style="box-sizing: border-box; padding: 0px; margin: 0px; border: 0px; outline: none; font-family: Tahoma, Geneva, sans-serif;">Aquela calça super comfy e estilosa para te acompanhar nesse inverno!</span></span></p>                        |                                 | 2022-05-26             | 2022-11-08              | http://orgbling.s3.amazonaws.com/358dd3a99dc65df69a3f3852c88a9c7f/t/ff947f17eb154298f3fb991594ab17b2?AWSAccessKeyId=AKIATCLMSGFX4J7TU445&Expires=1669817234&Signature=PPHn8S%2FTDDIGI0nKS3dYXXwfLR4%3D |                    |                          |                            |                 | 6006.32.20             |                |                0 |                        0 |                       |                       |                    nan |                nan |                           nan |                        |                5108713 | Calças                        |               0.3 |                0.31 |                       0 |                       0 |                |                         |                        1 |                       1 |                             1 | Centímetros             |                       0 |                 0 |                       |                      0 | Não Especificado   | N                     | P                  | 0000-00-00             |                        | S                        |                5.02 |
|    |              |                  |                                     |                |                    |                   |                 |                      | <p style="box-sizing: border-box; padding: 0px; border: 0px; outline: none; margin-block: 0px; color: #333333; font-family: Lato, sans-serif; font-size: 18px; background-color: #fefffe;"><span style="box-sizing: border-box; padding: 0px; margin: 0px; border: 0px; outline: none; font-size: 12px;"><span style="box-sizing: border-box; padding: 0px; margin: 0px; border: 0px; outline: none; font-family: Tahoma, Geneva, sans-serif;">Com moletom felpado e uma modelagem que abraça o corpo, ela é a nossa queridinha por aqui! &lt;3</span></span></p> |                                 |                        |                         |                                                                                                                                                                                                             |                    |                          |                            |                 |                        |                |                  |                          |                       |                       |                        |                    |                               |                        |                        |                               |                   |                     |                         |                         |                |                         |                          |                         |                               |                         |                         |                   |                       |                        |                    |                       |                    |                        |                        |                          |                     |
'''

Full code:

import requests
import pandas as pd
from pandas import json_normalize
import json

BLING_SECRET_KEY = my_apikey

def list_products(page=1):
    url = f'https://bling.com.br/Api/v2/produtos/page={page}/json/'
    payload = {'apikey': BLING_SECRET_KEY,}
    all_products = {'retorno': {'produtos': []}}

    if page == 'all':
        page = 1
        
        while True:
            url = f'https://bling.com.br/Api/v2/produtos/page={page}/json/'
            produtos = requests.get(url, params=payload)
            try:
                pagina = produtos.json()['retorno']['produtos']
                page += 1
                for item in pagina:
                    all_products['retorno']['produtos'].append(item)
            except KeyError:

                break

            df = json_normalize(all_products, 
                                meta=['produtos'])
            return df   
  

produtos = list_products('all')
df = pd.json_normalize(produtos.explode('retorno.produtos')['retorno.produtos'])

Answered By: Clegane
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.