InstagramのプロアカウントとInstagram graph API(version.16)とPython3とpandasとmatplotlibとStreamlitを用いる事ができる状況において、①自分がInstagramで投稿したコンテンツに投稿日を元にした"YYYYMMDD"というIDを付与(同日に複数投稿がある場合には枝番として"_1","_2"と付与)しリストから選択できるようにし、対象のコンテンツ画像をInstagramから自動でダウンロードして表示し、コンテンツに対する"いいね"数と"いいね"したユーザー名とユーザー画像の表示と隣にインプレッションから計算した"いいね"の割合のパーセントを表示するのが1列目、コンテンツに対するコメントとそのコメント実施ユーザー名とユーザー画像が2列目、コンテンツがきっかけでフォローを実施したユーザー名とユーザー画像の表示が3列目、これらの情報を1ペイン目で表示し、②2ペイン目で、すべてのコンテンツの取得可能なすべてのアナリティクス情報の各データをリストから選択し分析でき、インタラクティブなグラフやチャートを、1ペイン目と並行してStreamlitで表示できるようにし、③毎回の入力が不要なように事前に必要な情報はコードに埋め込んである設定のPythonコードを作成を希望しています。

'''
import json
import pandas as pd
import requests
import streamlit as st

from datetime import datetime
from matplotlib import pyplot as plt

# 事前に必要な情報を埋め込む
ACCESS_TOKEN = “”
USER_ID = “”

def get_post_id(timestamp: str, media_id: str, post_creation_dates: List[str]) -> str:
    date = datetime.strptime(timestamp, ‘%Y-%m-%dT%H:%M:%S%z’).strftime(‘%Y%m%d’)
    post_id = f"{date}_{post_creation_dates.count(date)+1}“
    post_creation_dates.append(date)
    return post_id

def get_media_data(media_id: str) -> Tuple[str, str]:
    media_url = f"https://graph.instagram.com/v12.0/{media_id}?fields=media_type,media_url,timestamp&access_token={ACCESS_TOKEN}”
    response = requests.get(media_url)
    response.raise_for_status() # Raise an exception if there’s an error in the response
    media_data = response.json()
    return media_data[“media_url”], media_data[“timestamp”]

def get_username_and_picture(user_id: str) -> Union[Tuple[str, str], Tuple[None, None]]:
    user_url = f"https://graph.instagram.com/v12.0/{user_id}?fields=username,profile_picture_url&access_token={ACCESS_TOKEN}“
    response = requests.get(user_url)
    if response.status_code != 200:
        return None, None
    user_data = response.json()
    return user_data[“username”], user_data[“profile_picture_url”]

def get_total_counts(count_type: str, media_id: str) -> int:
    if count_type not in [“likes”, “comments”]:
        return 0
    count_url = f"https://graph.instagram.com/v12.0/{media_id}?fields={count_type}.summary(true)&access_token={ACCESS_TOKEN}”
    response = requests.get(count_url)
    response.raise_for_status()  # Raise an exception if there’s an error in the response
    summary_data = response.json()
    return summary_data[“summary”][“total_count”]

def extract_data(response: requests.models.Response) -> pd.DataFrame:
    if response.text:
        response.raise_for_status()  # Raise an exception if there’s an error in the response
        data = json.loads(response.text)[“data”]
        return pd.DataFrame(data)
    return None

# Check if the access token and user ID are not empty
if not ACCESS_TOKEN:
    st.warning(“Please set your ACCESS_TOKEN in the code.”)
    st.stop()

if not USER_ID:
    st.warning(“Please set your USER_ID in the code.”)
    st.stop()

# Main logic
st.set_page_config(page_title=“Instagram Analytics”, layout=“wide”)

with st.sidebar:
    st.title(“Instagram Analytics”)

# Get media
media_url = f"https://graph.instagram.com/v12.0/{USER_ID}/media?fields=id,caption,timestamp&access_token={ACCESS_TOKEN}“
response = requests.get(media_url)
if response.status_code != 200:
    st.write(“An error occurred while fetching data from the API:”)
    st.write(response.json())
    st.stop()

media_df = extract_data(response)
if media_df is None:
    st.write(“No data available for the given ACCESS_TOKEN and USER_ID.”)
    st.stop()

# Add post ID
try:
    post_creation_dates = []
    media_df[“post_id”] = media_df.apply(
        lambda row: get_post_id(row[“timestamp”], row[“id”], post_creation_dates), axis=1
    )
except KeyError as e:
    st.error(f"An error occurred while processing the data: {str(e)}”)
    st.stop()

# Sidebar selectbox
selected_post = st.sidebar.selectbox(“Select Post:”, media_df[“post_id”].values)

with st.empty():
    col1, col2, col3 = st.columns([1, 1, 1])

    # Get selected post data
    selected_media_id = media_df.loc[
        media_df[“post_id”] == selected_post, “id”
    ].values[0]

    image_url, post_created_time = get_media_data(selected_media_id)
    col2.image(image_url, width=300)

with st.expander(“Analytics Pane”):
    total_likes = get_total_counts(“likes”, selected_media_id)
    total_comments = get_total_counts(“comments”, selected_media_id)
    col1.metric(“Total Likes”, total_likes)
    col1.metric(“Total Comments”, total_comments)

    # Display interactive graphs and charts of analytics data (sample data)
    sample_data = pd.DataFrame(
        {
            “dates”: pd.date_range(start=“2021-01-01”, periods=10, freq=“M”),
            “values”: [100, 150, 170, 200, 220, 250, 270, 300, 330, 350],
        }
    )
    selected_analytics = st.multiselect(“Select Analytics:”, sample_data.columns)

    if any(selected_analytics):
        fig, ax = plt.subplots()
        ax.plot(sample_data[selected_analytics])
        st.write(fig)

'''

上記コードを実行すると下記のエラーが発生します。行頭にPython用のインデントを付与した修正済みのコードを省略せずにすべて表示してください。

'''

JSONDecodeError                           Traceback (most recent call last)
File ~/.var/app/org.jupyter.JupyterLab/config/jupyterlab-desktop/jlab_server/lib/python3.8/site-packages/requests/models.py:971, in Response.json(self, **kwargs)
    970 try:
--> 971     return complexjson.loads(self.text, **kwargs)
    972 except JSONDecodeError as e:
    973     # Catch JSON-related errors and raise as requests.JSONDecodeError
    974     # This aliases json.JSONDecodeError and simplejson.JSONDecodeError

File ~/.var/app/org.jupyter.JupyterLab/config/jupyterlab-desktop/jlab_server/lib/python3.8/json/__init__.py:357, in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    354 if (cls is None and object_hook is None and
    355         parse_int is None and parse_float is None and
    356         parse_constant is None and object_pairs_hook is None and not kw):
--> 357     return _default_decoder.decode(s)
    358 if cls is None:

File ~/.var/app/org.jupyter.JupyterLab/config/jupyterlab-desktop/jlab_server/lib/python3.8/json/decoder.py:337, in JSONDecoder.decode(self, s, _w)
    333 """Return the Python representation of ``s`` (a ``str`` instance
    334 containing a JSON document).
    335 
    336 """
--> 337 obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    338 end = _w(s, end).end()

File ~/.var/app/org.jupyter.JupyterLab/config/jupyterlab-desktop/jlab_server/lib/python3.8/json/decoder.py:355, in JSONDecoder.raw_decode(self, s, idx)
    354 except StopIteration as err:
--> 355     raise JSONDecodeError("Expecting value", s, err.value) from None
    356 return obj, end

JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

JSONDecodeError                           Traceback (most recent call last)
Cell In[82], line 70
     68 if response.status_code != 200:
     69     st.write("An error occurred while fetching data from the API:")
---> 70     st.write(response.json())
     71     st.stop()
     73 media_df = extract_data(response)

File ~/.var/app/org.jupyter.JupyterLab/config/jupyterlab-desktop/jlab_server/lib/python3.8/site-packages/requests/models.py:975, in Response.json(self, **kwargs)
    971     return complexjson.loads(self.text, **kwargs)
    972 except JSONDecodeError as e:
    973     # Catch JSON-related errors and raise as requests.JSONDecodeError
    974     # This aliases json.JSONDecodeError and simplejson.JSONDecodeError
--> 975     raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)

JSONDecodeError: Expecting value: line 1 column 1 (char 0)

'''