File size: 6,812 Bytes
0e084ea
 
 
 
 
 
554e002
0e084ea
 
cb57a13
0e084ea
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cb57a13
0e084ea
 
554e002
 
 
 
 
 
0e084ea
 
 
 
 
 
 
 
 
 
554e002
 
 
 
 
 
0e084ea
 
 
 
 
 
 
 
 
 
554e002
 
 
 
 
 
0e084ea
 
 
 
 
 
 
 
554e002
 
0e084ea
554e002
2bc2c9f
554e002
0e084ea
 
 
 
 
 
2bc2c9f
554e002
2bc2c9f
554e002
 
 
0e084ea
 
2bc2c9f
cb57a13
2bc2c9f
0e084ea
 
 
 
cb57a13
0e084ea
 
 
 
 
 
 
 
cb57a13
0e084ea
 
 
 
 
 
 
2bc2c9f
 
0e084ea
2bc2c9f
 
0e084ea
 
cb57a13
0e084ea
 
2bc2c9f
0e084ea
 
 
cb57a13
0e084ea
 
 
 
554e002
 
0e084ea
 
 
 
554e002
0e084ea
 
 
 
 
 
 
 
554e002
 
0e084ea
 
 
 
554e002
0e084ea
 
 
 
 
 
 
 
 
 
 
 
 
 
 
554e002
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
import streamlit as st
import requests
import pandas as pd
import os 

# ---------------------------
# Global Variables
# ---------------------------
API_KEY = os.getenv("FMP_API_KEY")
DEFAULT_RSS_PAGE = 5  # User no longer sees this. We fetch page=5 by default.
DEFAULT_SEARCH_NAME = "enotap"
DEFAULT_CIK = "0001916078"

# ---------------------------
# Initialize Session State
# ---------------------------
if "run_rss" not in st.session_state:
    st.session_state.run_rss = False
if "run_search" not in st.session_state:
    st.session_state.run_search = False
if "run_cik" not in st.session_state:
    st.session_state.run_cik = False

if "rss_page" not in st.session_state:
    st.session_state.rss_page = DEFAULT_RSS_PAGE
if "search_name" not in st.session_state:
    st.session_state.search_name = DEFAULT_SEARCH_NAME
if "cik_value" not in st.session_state:
    st.session_state.cik_value = DEFAULT_CIK

# ---------------------------
# CACHED API FUNCTIONS
# ---------------------------
@st.cache_data(show_spinner=False)
def fetch_crowdfunding_rss(page: int) -> pd.DataFrame:
    """
    Fetch the crowdfunding live feed data for the given page.
    """
    url = f"https://financialmodelingprep.com/api/v4/crowdfunding-offerings-rss-feed?page={page}&apikey={API_KEY}"
    try:
        response = requests.get(url)
        response.raise_for_status()
        data = response.json()
    except:
        return pd.DataFrame()
    if not data:
        return pd.DataFrame()
    return pd.DataFrame(data)

@st.cache_data(show_spinner=False)
def fetch_crowdfunding_search(name: str) -> pd.DataFrame:
    """
    Search for crowdfunding campaigns by name.
    """
    url = f"https://financialmodelingprep.com/api/v4/crowdfunding-offerings/search?name={name}&apikey={API_KEY}"
    try:
        response = requests.get(url)
        response.raise_for_status()
        data = response.json()
    except:
        return pd.DataFrame()
    if not data:
        return pd.DataFrame()
    return pd.DataFrame(data)

@st.cache_data(show_spinner=False)
def fetch_crowdfunding_by_cik(cik: str) -> pd.DataFrame:
    """
    Fetch all crowdfunding campaigns launched by a company identified by its CIK.
    """
    url = f"https://financialmodelingprep.com/api/v4/crowdfunding-offerings?cik={cik}&apikey={API_KEY}"
    try:
        response = requests.get(url)
        response.raise_for_status()
        data = response.json()
    except:
        return pd.DataFrame()
    if not data:
        return pd.DataFrame()
    return pd.DataFrame(data)

# ---------------------------
# MAIN APP
# ---------------------------
def main():
    st.set_page_config(page_title="Crowdfunding Campaigns", layout="wide")
    st.title("Crowdfunding Campaigns")
    st.write(
        "Access real-time crowdfunding campaign data. "
        "Use the side menu to select one of the three pages below. "
        "Each page provides a table with specific campaign details."
    )
    
    # Sidebar: Navigation and Options
    with st.sidebar.expander("Navigation and Options", expanded=True):
        page = st.radio(
            "Select Page",
            ("Crowdfunding Live Feed", "Crowdfunding Search", "Crowdfunding By CIK"),
            help=(
                "Crowdfunding Live Feed: View up-to-date campaign data. "
                "Crowdfunding Search: Find campaigns by name. "
                "Crowdfunding By CIK: Show campaigns for a company by its CIK."
            )
        )
        
        if page == "Crowdfunding Live Feed":
            # Removed the page input from the user.
            if st.button("Run Crowdfunding Live Feed"):
                st.session_state.run_rss = True
        elif page == "Crowdfunding Search":
            search_name = st.text_input(
                "Campaign/Company Name",
                value=st.session_state.search_name,
                help="Enter the name to search for crowdfunding campaigns (e.g., enotap)."
            )
            st.session_state.search_name = search_name
            if st.button("Run Crowdfunding Search"):
                st.session_state.run_search = True
        else:  # Crowdfunding By CIK
            cik_value = st.text_input(
                "Company CIK",
                value=st.session_state.cik_value,
                help="Enter the CIK of the company to fetch its crowdfunding campaigns."
            )
            st.session_state.cik_value = cik_value
            if st.button("Run Crowdfunding By CIK"):
                st.session_state.run_cik = True

    # Page Output
    if page == "Crowdfunding Live Feed":
        st.header("Crowdfunding Live Feed")
        st.write(
            "Displays the latest crowdfunding campaigns from a live feed. "
            "Includes details such as company name, form type, offering amount, and more."
        )
        if st.session_state.run_rss:
            # The default is set to page=5 in the code. The user cannot change it.
            df_rss = fetch_crowdfunding_rss(st.session_state.rss_page)
            if df_rss.empty:
                st.error("No data found for that feed page.")
            else:
                st.dataframe(df_rss, use_container_width=True)
        else:
            st.info("Click 'Run Crowdfunding Live Feed' to fetch the live feed.")
    
    elif page == "Crowdfunding Search":
        st.header("Crowdfunding Search")
        st.write(
            "Search for crowdfunding campaigns by company or campaign name. "
            "The table below shows all matching results."
        )
        if st.session_state.run_search:
            df_search = fetch_crowdfunding_search(st.session_state.search_name)
            if df_search.empty:
                st.error("No crowdfunding campaigns found for that name.")
            else:
                st.dataframe(df_search, use_container_width=True)
        else:
            st.info("Enter a name in the sidebar and click 'Run Crowdfunding Search'.")
    
    else:  # Crowdfunding By CIK
        st.header("Crowdfunding By CIK")
        st.write(
            "Shows all crowdfunding campaigns for a company identified by its CIK. "
            "The table below contains details for each campaign."
        )
        if st.session_state.run_cik:
            df_cik = fetch_crowdfunding_by_cik(st.session_state.cik_value)
            if df_cik.empty:
                st.error("No crowdfunding campaigns found for that CIK.")
            else:
                st.dataframe(df_cik, use_container_width=True)
        else:
            st.info("Enter a CIK in the sidebar and click 'Run Crowdfunding By CIK'.")

if __name__ == "__main__":
    main()


hide_streamlit_style = """
<style>
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
</style>
"""
st.markdown(hide_streamlit_style, unsafe_allow_html=True)