admin08077 commited on
Commit
70a62e7
·
verified ·
1 Parent(s): faa7170

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +327 -0
app.py ADDED
@@ -0,0 +1,327 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests
3
+ import base64
4
+ import uuid
5
+ import os
6
+ from dotenv import load_dotenv
7
+ from datetime import datetime, date
8
+ import plaid
9
+ from plaid import Client as PlaidClient
10
+ import stripe
11
+
12
+ # Load environment variables from .env file
13
+ load_dotenv()
14
+
15
+ # Set page config
16
+ st.set_page_config(
17
+ page_title="TransactPro: Unified Financial Platform",
18
+ page_icon="💳",
19
+ layout="wide",
20
+ )
21
+
22
+ # Title of the app
23
+ st.title("TransactPro: Unified Financial Platform")
24
+ st.subheader("Made by Citibank Demo Business Inc.")
25
+
26
+ # Sidebar for API keys and configuration
27
+ st.sidebar.header("API Configuration")
28
+
29
+ # Modern Treasury Configuration
30
+ st.sidebar.subheader("Modern Treasury")
31
+ mt_api_key = st.sidebar.text_input("Modern Treasury API Key", type="password", value=os.getenv('MT_API_KEY'))
32
+ mt_organization_id = st.sidebar.text_input("Organization ID", value=os.getenv('MT_ORG_ID'))
33
+
34
+ # Citibank API Configuration
35
+ st.sidebar.subheader("Citibank API")
36
+ citibank_client_id = st.sidebar.text_input("Citibank Client ID", value=os.getenv('CITIBANK_CLIENT_ID'))
37
+ citibank_client_secret = st.sidebar.text_input("Citibank Client Secret", type="password", value=os.getenv('CITIBANK_CLIENT_SECRET'))
38
+ citibank_api_key = st.sidebar.text_input("Citibank API Key", value=os.getenv('CITIBANK_API_KEY'))
39
+
40
+ # Plaid API Configuration
41
+ st.sidebar.subheader("Plaid API")
42
+ plaid_client_id = st.sidebar.text_input("Plaid Client ID", value=os.getenv('PLAID_CLIENT_ID'))
43
+ plaid_secret = st.sidebar.text_input("Plaid Secret", type="password", value=os.getenv('PLAID_SECRET'))
44
+ plaid_env = st.sidebar.selectbox("Plaid Environment", ["sandbox", "development", "production"], index=0)
45
+
46
+ # Stripe API Configuration
47
+ st.sidebar.subheader("Stripe API")
48
+ stripe_api_key = st.sidebar.text_input("Stripe API Key", type="password", value=os.getenv('STRIPE_API_KEY'))
49
+ if stripe_api_key:
50
+ stripe.api_key = stripe_api_key
51
+
52
+ # Main application
53
+ endpoint_choice = st.selectbox("Choose Service", [
54
+ "Citibank API",
55
+ "Plaid API",
56
+ "Stripe API",
57
+ "Modern Treasury",
58
+ ])
59
+
60
+ # Helper functions
61
+
62
+ def create_basic_auth_header(org_id, api_key):
63
+ # Combine Organization ID and API Key, separated by a colon
64
+ credentials = f"{org_id}:{api_key}"
65
+ # Encode the credentials in base64
66
+ base64_credentials = base64.b64encode(credentials.encode()).decode('utf-8')
67
+ # Return the full Authorization header
68
+ return f"Basic {base64_credentials}"
69
+
70
+ def fetch_modern_treasury_data(api_key, org_id, endpoint):
71
+ base_url = "https://app.moderntreasury.com/api/"
72
+ endpoints = {
73
+ "Payment Orders": "payment_orders",
74
+ "Expected Payments": "expected_payments",
75
+ "Returns": "returns",
76
+ "Incoming Payment Details": "incoming_payment_details",
77
+ "Counterparties": "counterparties",
78
+ "Internal Accounts": "internal_accounts",
79
+ "Ledgers": "ledgers",
80
+ "Ledger Accounts": "ledger_accounts"
81
+ }
82
+ url = base_url + endpoints[endpoint]
83
+ headers = {
84
+ "Authorization": create_basic_auth_header(org_id, api_key)
85
+ }
86
+ response = requests.get(url, headers=headers)
87
+
88
+ if response.status_code == 200:
89
+ return response.json()
90
+ else:
91
+ st.error(f"Error: {response.status_code} - {response.text}")
92
+ return None
93
+
94
+ # Citibank Service Class
95
+ class CitibankService:
96
+ def __init__(self, client_id, client_secret, api_key):
97
+ self.client_id = client_id
98
+ self.client_secret = client_secret
99
+ self.api_key = api_key
100
+ self.token_url = "https://sandbox.apihub.citi.com/gcb/api/clientCredentials/oauth2/token/us/gcb"
101
+ self.base_url = "https://sandbox.apihub.citi.com/gcb/api/v1"
102
+
103
+ def get_access_token(self):
104
+ payload = {
105
+ "grant_type": "client_credentials",
106
+ "scope": "accounts_details_transactions"
107
+ }
108
+ headers = {
109
+ "Authorization": f"Basic {self._encode_credentials()}",
110
+ "Content-Type": "application/x-www-form-urlencoded"
111
+ }
112
+ response = requests.post(self.token_url, data=payload, headers=headers)
113
+ if response.status_code == 200:
114
+ return response.json()["access_token"]
115
+ else:
116
+ st.error(f"Error obtaining access token: {response.text}")
117
+ return None
118
+
119
+ def get_accounts(self, access_token):
120
+ headers = {
121
+ "Authorization": f"Bearer {access_token}",
122
+ "client_id": self.client_id,
123
+ "uuid": str(uuid.uuid4()),
124
+ "Accept": "application/json"
125
+ }
126
+ url = f"{self.base_url}/accounts"
127
+ response = requests.get(url, headers=headers)
128
+ if response.status_code == 200:
129
+ return response.json()
130
+ else:
131
+ st.error(f"Error fetching accounts: {response.text}")
132
+ return None
133
+
134
+ def get_transactions(self, access_token, account_id, from_date, to_date):
135
+ headers = {
136
+ "Authorization": f"Bearer {access_token}",
137
+ "client_id": self.client_id,
138
+ "uuid": str(uuid.uuid4()),
139
+ "Accept": "application/json"
140
+ }
141
+ params = {
142
+ "transactionFromDate": from_date,
143
+ "transactionToDate": to_date
144
+ }
145
+ url = f"{self.base_url}/accounts/{account_id}/transactions"
146
+ response = requests.get(url, headers=headers, params=params)
147
+ if response.status_code == 200:
148
+ return response.json()
149
+ else:
150
+ st.error(f"Error fetching transactions: {response.text}")
151
+ return None
152
+
153
+ def _encode_credentials(self):
154
+ credentials = f"{self.client_id}:{self.client_secret}"
155
+ return base64.b64encode(credentials.encode()).decode()
156
+
157
+ # Plaid Service Class
158
+ class PlaidService:
159
+ def __init__(self, client_id, secret, environment):
160
+ env = getattr(plaid.Environment, environment.capitalize())
161
+ self.client = PlaidClient(
162
+ client_id=client_id,
163
+ secret=secret,
164
+ environment=env
165
+ )
166
+
167
+ def create_link_token(self):
168
+ configs = {
169
+ 'user': {
170
+ 'client_user_id': str(uuid.uuid4())
171
+ },
172
+ 'client_name': 'TransactPro',
173
+ 'products': ['auth', 'transactions'],
174
+ 'country_codes': ['US'],
175
+ 'language': 'en',
176
+ }
177
+ response = self.client.LinkToken.create(configs)
178
+ return response['link_token']
179
+
180
+ def exchange_public_token(self, public_token):
181
+ response = self.client.Item.public_token.exchange(public_token)
182
+ return response['access_token']
183
+
184
+ def get_accounts(self, access_token):
185
+ response = self.client.Accounts.get(access_token)
186
+ return response['accounts']
187
+
188
+ def get_transactions(self, access_token, start_date, end_date):
189
+ response = self.client.Transactions.get(access_token, start_date, end_date)
190
+ return response['transactions']
191
+
192
+ # Main application logic
193
+
194
+ if endpoint_choice == "Citibank API":
195
+ st.header("Citibank API Integration")
196
+ if not citibank_client_id or not citibank_client_secret or not citibank_api_key:
197
+ st.error("Please provide Citibank API credentials in the sidebar.")
198
+ else:
199
+ citibank_service = CitibankService(citibank_client_id, citibank_client_secret, citibank_api_key)
200
+ access_token = citibank_service.get_access_token()
201
+ if access_token:
202
+ citibank_action = st.selectbox("Choose an action", [
203
+ "Retrieve Account Details",
204
+ "Retrieve Transactions"
205
+ ])
206
+
207
+ if citibank_action == "Retrieve Account Details":
208
+ data = citibank_service.get_accounts(access_token)
209
+ if data:
210
+ st.json(data)
211
+ elif citibank_action == "Retrieve Transactions":
212
+ account_id = st.text_input("Enter Account ID")
213
+ from_date = st.date_input("From Date", value=date.today())
214
+ to_date = st.date_input("To Date", value=date.today())
215
+ if account_id and from_date and to_date:
216
+ data = citibank_service.get_transactions(
217
+ access_token, account_id, from_date.strftime("%Y-%m-%d"), to_date.strftime("%Y-%m-%d")
218
+ )
219
+ if data:
220
+ st.json(data)
221
+ else:
222
+ st.info("Please enter Account ID and select From and To dates.")
223
+
224
+ elif endpoint_choice == "Plaid API":
225
+ st.header("Plaid API Integration")
226
+ if not plaid_client_id or not plaid_secret:
227
+ st.error("Please provide Plaid API credentials in the sidebar.")
228
+ else:
229
+ plaid_service = PlaidService(plaid_client_id, plaid_secret, plaid_env)
230
+ st.write("Initializing Plaid Link...")
231
+ link_token = plaid_service.create_link_token()
232
+ st.write("Link Token created. Use this token in your frontend to initialize Plaid Link.")
233
+ st.code(link_token, language='text')
234
+ public_token = st.text_input("Enter Public Token (from Plaid Link)")
235
+ if public_token:
236
+ access_token_response = plaid_service.exchange_public_token(public_token)
237
+ access_token = access_token_response['access_token']
238
+ st.write("Access Token obtained.")
239
+ st.code(access_token, language='text')
240
+ plaid_action = st.selectbox("Choose an action", [
241
+ "Get Accounts",
242
+ "Get Transactions"
243
+ ])
244
+ if plaid_action == "Get Accounts":
245
+ accounts = plaid_service.get_accounts(access_token)
246
+ st.json(accounts)
247
+ elif plaid_action == "Get Transactions":
248
+ start_date = st.date_input("Start Date", value=date.today())
249
+ end_date = st.date_input("End Date", value=date.today())
250
+ if start_date and end_date:
251
+ transactions = plaid_service.get_transactions(
252
+ access_token, start_date.strftime("%Y-%m-%d"), end_date.strftime("%Y-%m-%d")
253
+ )
254
+ st.json(transactions)
255
+ else:
256
+ st.info("Please select Start and End dates.")
257
+
258
+ elif endpoint_choice == "Stripe API":
259
+ st.header("Stripe API Integration")
260
+ if not stripe_api_key:
261
+ st.error("Please provide the Stripe API Key in the sidebar.")
262
+ else:
263
+ stripe_action = st.selectbox("Choose an action", [
264
+ "Create Account Link",
265
+ "Create Account Session"
266
+ ])
267
+ if stripe_action == "Create Account Link":
268
+ account_id = st.text_input("Enter Connected Account ID")
269
+ if account_id:
270
+ try:
271
+ account_link = stripe.AccountLink.create(
272
+ account=account_id,
273
+ refresh_url="https://example.com/reauth",
274
+ return_url="https://example.com/return",
275
+ type="account_onboarding",
276
+ )
277
+ st.write("Account Link created:")
278
+ st.write(account_link.url)
279
+ except Exception as e:
280
+ st.error(f"Error: {e}")
281
+ else:
282
+ st.info("Please enter a Connected Account ID.")
283
+
284
+ elif stripe_action == "Create Account Session":
285
+ account_id = st.text_input("Enter Connected Account ID")
286
+ if account_id:
287
+ try:
288
+ account_session = stripe.AccountSession.create(
289
+ account=account_id,
290
+ components={
291
+ "account_onboarding": {"enabled": True},
292
+ "payments": {"enabled": True},
293
+ "payouts": {"enabled": True},
294
+ "balances": {"enabled": True},
295
+ }
296
+ )
297
+ st.write("Account Session created:")
298
+ st.write("Client Secret:")
299
+ st.code(account_session.client_secret, language='text')
300
+ except Exception as e:
301
+ st.error(f"Error: {e}")
302
+ else:
303
+ st.info("Please enter a Connected Account ID.")
304
+
305
+ elif endpoint_choice == "Modern Treasury":
306
+ st.header("Modern Treasury API Integration")
307
+ endpoint = st.selectbox("Choose Endpoint", [
308
+ "Payment Orders",
309
+ "Expected Payments",
310
+ "Returns",
311
+ "Incoming Payment Details",
312
+ "Counterparties",
313
+ "Internal Accounts",
314
+ "Ledgers",
315
+ "Ledger Accounts"
316
+ ])
317
+ if st.button("Fetch Data"):
318
+ if mt_api_key and mt_organization_id:
319
+ data = fetch_modern_treasury_data(mt_api_key, mt_organization_id, endpoint)
320
+ if data:
321
+ st.json(data)
322
+ else:
323
+ st.error("Please provide both a valid API key and Organization ID.")
324
+
325
+ # Display footer
326
+ st.sidebar.markdown("Powered by Streamlit")
327
+ st.sidebar.markdown("Made by Citibank Demo Business Inc.")