01-Categorization-Transactions

#1
.vscode/settings.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ {
2
+ "jupyter.notebookFileRoot": "${workspaceFolder}"
3
+ }
app/categorization/__init__.py ADDED
File without changes
app/categorization/categorizer.py ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Standard library imports
2
+ import re
3
+ import ast
4
+ import json
5
+ import logging
6
+ import os
7
+ from typing import Any, List, Tuple, Optional, Dict, Union
8
+
9
+ # Third-party library imports
10
+ import numpy as np
11
+ import pandas as pd
12
+ import asyncio
13
+ from rapidfuzz import process
14
+ from tenacity import retry, wait_random_exponential, stop_after_attempt
15
+ from pydantic import ValidationError
16
+
17
+ # Local application/library specific imports
18
+ from langchain_openai import ChatOpenAI
19
+ from langchain.chains import LLMChain
20
+ from langchain.output_parsers import PydanticOutputParser, OutputFixingParser
21
+ from langchain.prompts import PromptTemplate
22
+ import app.categorization.template as CATEGORY_TEMPLATE
23
+ from app.categorization.config import CATEGORY_REFERENCE_OUTPUT_FILE, TX_PER_LLM_RUN
24
+
25
+
26
+ def fuzzy_match_list_categorizer(
27
+ description: str,
28
+ descriptions: np.ndarray,
29
+ description_category_pairs: pd.DataFrame,
30
+ threshold: int = 75,
31
+ ) -> Optional[str]:
32
+ """Find the most similar transaction description and return its category.
33
+
34
+ This function uses fuzzy string matching to compare the input description
35
+ against a list of known descriptions. If a sufficient match is found,
36
+ the function returns the category associated with the matched description.
37
+
38
+ Args:
39
+ description (str): The transaction description to categorize.
40
+ descriptions (np.ndarray): Known descriptions to compare against.
41
+ description_category_pairs (pd.DataFrame): DataFrame mapping descriptions to categories.
42
+ threshold (int): Minimum similarity score to consider a match.
43
+
44
+ Returns:
45
+ str or None: Category of the matched description, or None if no match found.
46
+ """
47
+
48
+ # Fuzzy-match this description against the reference descriptions
49
+ match_results = process.extractOne(
50
+ description, descriptions, score_cutoff=threshold)
51
+
52
+ # If a match is found, return the category of the matched description
53
+ if match_results:
54
+ return description_category_pairs.at[match_results[2], 'category']
55
+
56
+ return None
57
+
58
+
59
+ async def llm_list_categorizer(tx_list: pd.DataFrame) -> pd.DataFrame:
60
+ """Categorize a list of transactions using a language model.
61
+
62
+ This function uses a Language Model (LLM) to categorize a list of transaction descriptions.
63
+ It splits the input DataFrame into chunks and processes each chunk asynchronously to improve performance.
64
+
65
+ Args:
66
+ tx_list (pd.DataFrame): DataFrame containing the transaction descriptions to categorize.
67
+
68
+ Returns:
69
+ pd.DataFrame: DataFrame mapping transaction descriptions to their inferred categories.
70
+ """
71
+
72
+ # Initialize language model and prompt
73
+ openai_api_key = os.environ['OPENAI_API_KEY']
74
+ llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo-0125",
75
+ api_key=openai_api_key)
76
+ prompt = PromptTemplate.from_template(template=CATEGORY_TEMPLATE)
77
+ chain = LLMChain(llm=llm, prompt=prompt)
78
+
79
+ # Iterate over the DataFrame in batches of TX_PER_LLM_RUN transactions
80
+ tasks = [llm_sublist_categorizer(tx_list.attrs['file_name'], chain=chain, tx_descriptions="\n".join(chunk['name/description']).strip())
81
+ for chunk in np.array_split(tx_list, tx_list.shape[0] // TX_PER_LLM_RUN + 1)]
82
+
83
+ # Gather results and extract (valid) outputs
84
+ # The results variable is a list of 'results', each 'result' being the output of a single LLM run
85
+ results = await asyncio.gather(*tasks)
86
+
87
+ # Extract valid results (each valid result is a list of description-category pairs)
88
+ valid_results = [result['output'] for result in results if result['valid']]
89
+
90
+ # Flatten the list of valid results to obtain a single list of description-category pairs
91
+ valid_outputs = [
92
+ output for valid_result in valid_results for output in valid_result]
93
+
94
+ # Return a DataFrame with the valid outputs
95
+ return pd.DataFrame(valid_outputs, columns=['name/description', 'category'])
96
+
97
+
98
+ @retry(wait=wait_random_exponential(min=1, max=20), stop=stop_after_attempt(6))
99
+ async def llm_sublist_categorizer(
100
+ file_name: str,
101
+ chain: LLMChain,
102
+ tx_descriptions: str,
103
+ ) -> Dict[str, Union[bool, List[Tuple[str, str]]]]:
104
+ """Categorize a batch of transactions using a language model.
105
+
106
+ This function takes a batch of transaction descriptions and passes them to a language model
107
+ for categorization. The function retries on failure, with an exponential backoff.
108
+
109
+ Args:
110
+ file_name (str): Name of the file the transaction descriptions were extracted from.
111
+ chain (LLMChain): Language model chain to use for categorization.
112
+ tx_descriptions (str): Concatenated transaction descriptions to categorize.
113
+
114
+ Returns:
115
+ dict: Dictionary containing a 'valid' flag and a list of categorized descriptions.
116
+ """
117
+
118
+ raw_result = await chain.arun(input_data=tx_descriptions)
119
+
120
+ logger = logging.getLogger(__name__)
121
+ result = {'valid': True, 'output': []}
122
+ try:
123
+ # Create a pattern to match a list Description-Category pairs (List[Tuple[str, str]])
124
+ pattern = r"\['([^']+)', '([^']+)'\]"
125
+
126
+ # Use it to extract all the correctly formatted pairs from the raw result
127
+ matches = re.findall(pattern, raw_result.replace("\\'", "'"))
128
+
129
+ # Loop over the matches, and try to parse them to ensure the content is valid
130
+ valid_outputs = []
131
+ for match in matches:
132
+ try:
133
+ parsed_pair = ast.literal_eval(str(list(match)))
134
+ valid_outputs.append(parsed_pair)
135
+ except Exception as e:
136
+ logger.log(logging.ERROR,
137
+ f"Parsing Error: {e}\nMatch: {match}\n")
138
+ result['valid'] = False
139
+
140
+ result['output'] = valid_outputs
141
+
142
+ except Exception as e:
143
+ logging.log(
144
+ logging.ERROR, f"| File: {file_name} | Unexpected Error: {e}\nRaw Result: {raw_result}")
145
+ result['valid'] = False
146
+
147
+ return result
app/categorization/categorizer_list.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Standard library imports
2
+ import os
3
+ from datetime import datetime
4
+
5
+ # Third-party library imports
6
+ import pandas as pd
7
+
8
+ # Local application/library specific imports
9
+ from app.categorization.config import CATEGORY_REFERENCE_OUTPUT_FILE
10
+ from app.categorization.categorizer import llm_list_categorizer, fuzzy_match_list_categorizer
11
+
12
+
13
+ async def categorize_list(tx_list: pd.DataFrame) -> pd.DataFrame:
14
+ """Asynchronously categorize a list of transactions.
15
+
16
+ This function categorizes a list of transactions using a combination of fuzzy matching
17
+ and a language model. It looks up new transaction descriptions in the reference file
18
+ (a combination of user input and previous executions) to minimize API calls.
19
+ Any uncategorized transactions are sent to the language model, and new description-category
20
+ pairs are added to the reference file.
21
+
22
+ Args:
23
+ tx_list (pd.DataFrame): The list of transactions to categorize.
24
+
25
+ Returns:
26
+ pd.DataFrame: The original DataFrame with an additional column for the category.
27
+ """
28
+
29
+ if os.path.exists(CATEGORY_REFERENCE_OUTPUT_FILE):
30
+ # Read description-category pairs from the reference file
31
+ description_category_pairs = pd.read_csv(
32
+ CATEGORY_REFERENCE_OUTPUT_FILE, header=None, names=['name/description', 'category']
33
+ )
34
+
35
+ # Extract only descriptions for faster matching
36
+ descriptions = description_category_pairs['name/description'].values
37
+
38
+ # Use fuzzy matching to find similar descriptions and assign the category
39
+ tx_list['category'] = tx_list['name/description'].apply(
40
+ fuzzy_match_list_categorizer,
41
+ args=(descriptions, description_category_pairs),
42
+ )
43
+
44
+ # Filter out uncategorized transactions, deduplicate, and sort by description
45
+ uncategorized_descriptions = (
46
+ tx_list[tx_list['category'].isnull()]
47
+ .drop_duplicates(subset=['name/description'])
48
+ .sort_values(by=['name/description'])
49
+ )
50
+
51
+ # Ask the language model to categorize the remaining descriptions
52
+ if not uncategorized_descriptions.empty:
53
+ categorized_descriptions = await llm_list_categorizer(
54
+ uncategorized_descriptions[['name/description', 'category']]
55
+ )
56
+
57
+ categorized_descriptions.dropna(inplace=True)
58
+
59
+ # Update the category for uncategorized transactions based on the language model results
60
+ if not categorized_descriptions.empty:
61
+ tx_list['category'] = tx_list['category'].fillna(
62
+ tx_list['name/description'].map(
63
+ categorized_descriptions.set_index('name/description')['category']
64
+ )
65
+ )
66
+
67
+ # Fill remaining NaN values in 'category' with 'Other'
68
+ tx_list['category'] = tx_list['category'].fillna('Other')
69
+
70
+ return tx_list
app/categorization/config.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ # Data Folders
2
+ RESULT_OUTPUT_FILE = 'data/tx_data/output/result_master_data.csv'
3
+ CATEGORY_REFERENCE_OUTPUT_FILE = 'data/ref_data/category_ref_master_data.csv'
4
+
5
+ # LLM CONFIG
6
+ TX_PER_LLM_RUN = 10
app/categorization/file_processing.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import glob
3
+ import shutil
4
+ import logging
5
+ import warnings
6
+ from typing import Optional, Union, Dict, List
7
+ from datetime import datetime
8
+
9
+ import pandas as pd
10
+ from dateparser import parse
11
+
12
+ from app.categorization.categorizer_list import categorize_list
13
+ from app.categorization.config import RESULT_OUTPUT_FILE, CATEGORY_REFERENCE_OUTPUT_FILE
14
+
15
+ # Read file and process it (e.g. categorize transactions)
16
+ async def process_file(file_path: str) -> Dict[str, Union[str, pd.DataFrame]]:
17
+ """
18
+ Process the input file by reading, cleaning, standardizing, and categorizing the transactions.
19
+
20
+ Args:
21
+ file_path (str): Path to the input file.
22
+
23
+ Returns:
24
+ Dict[str, Union[str, pd.DataFrame]]: Dictionary containing the file name, processed output, and error information if any
25
+ """
26
+
27
+ file_name = os.path.basename(file_path)
28
+ result= {'file_name': file_name, 'output': pd.DataFrame(), 'error': ''}
29
+ try:
30
+ # Read file into standardized tx format: source, date, type, category, description, amount
31
+ tx_list = standardize_csv_file(file_path)
32
+
33
+ # Categorize transactions
34
+ result['output'] = await categorize_list(tx_list)
35
+ print(f'File processed sucessfully: {file_name}')
36
+
37
+ except Exception as e:
38
+ # Return an error indicator and exception info
39
+ logging.log(logging.ERROR, f"| File: {file_name} | Unexpected Error: {e}")
40
+ print(f'ERROR processing file {file_name}: {e}')
41
+ result['error'] = str(e)
42
+
43
+ return result
44
+
45
+
46
+
47
+ def standardize_csv_file(file_path: str) -> pd.DataFrame:
48
+ """
49
+ Read and prepare the data from the input file.
50
+
51
+ Args:
52
+ file_path (str): Path to the input file.
53
+
54
+ Returns:
55
+ pd.DataFrame: Prepared transaction data.
56
+ """
57
+
58
+ tx_list = pd.read_csv(file_path, index_col=False)
59
+ tx_list.attrs['file_name'] = file_path
60
+ tx_list.columns = tx_list.columns.str.lower().str.strip()
61
+
62
+ # Standardize dates to YYYY/MM/DD format
63
+ tx_list['date'] = pd.to_datetime(tx_list['date']).dt.strftime('%Y/%m/%d')
64
+
65
+ # Add source and reindex to desired tx format; category column is new and therefore empty
66
+ tx_list.loc[:, 'source'] = os.path.basename(file_path)
67
+ tx_list = tx_list.reindex(columns=['date', 'expense/income', 'category', 'name/description', 'amount'])
68
+
69
+ return tx_list
70
+
71
+
72
+ def save_results(results: List) -> None:
73
+ """
74
+ Merge all interim results in the input folder and write the merged results to the output file.
75
+
76
+ Args:
77
+ in_folder (str): Path to the input folder containing interim results.
78
+ out_file (str): Path to the output file.
79
+
80
+ Returns:
81
+ None
82
+ """
83
+
84
+ # Concatenate all (valid) results into a single DataFrame
85
+ # Print errors to console
86
+ ok_files = []
87
+ ko_files = []
88
+ error_messages = []
89
+
90
+ col_list = ['date', 'expense/income', 'category', 'name/description', 'amount']
91
+ tx_list = pd.DataFrame(columns=col_list)
92
+ for result in results:
93
+ if not result['error']:
94
+ ok_files.append(result['file_name'])
95
+ result_df = result['output']
96
+ result_df.columns = col_list
97
+ tx_list = pd.concat([tx_list, result_df], ignore_index=True)
98
+ else:
99
+ ko_files.append(result['file_name'])
100
+ error_messages.append(f"{result['file_name']}: {result['error']}")
101
+
102
+ # Write contents to output file (based on file type)
103
+ tx_list.to_csv(RESULT_OUTPUT_FILE, mode="a", index=False, header=not os.path.exists(RESULT_OUTPUT_FILE))
104
+
105
+ new_ref_data = tx_list[['name/description', 'category']]
106
+ if os.path.exists(CATEGORY_REFERENCE_OUTPUT_FILE):
107
+ # If it exists, add master file to interim results
108
+ old_ref_data = pd.read_csv(CATEGORY_REFERENCE_OUTPUT_FILE, names=['name/description', 'category'], header=0)
109
+ new_ref_data = pd.concat([old_ref_data, new_ref_data], ignore_index=True)
110
+
111
+ # Drop duplicates, sort, and write to create new Master File
112
+ new_ref_data.drop_duplicates(subset=['name/description']).sort_values(by=['name/description']).to_csv(CATEGORY_REFERENCE_OUTPUT_FILE, mode="w", index=False, header=True)
113
+
114
+ # Summarize results
115
+ print(f"\nProcessed {len(results)} files: {len(ok_files)} successful, {len(ko_files)} with errors\n")
116
+ if len(ko_files):
117
+ print(f"Errors in the following files:")
118
+ for message in error_messages:
119
+ print(f" {message}")
120
+ print('\n')
app/categorization/template.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CATEGORY_TEMPLATE = """
2
+ <context>
3
+ Your task is to create a list of [description, category] lists, where in each list item:
4
+ - the description is exactly the same you receive as input
5
+ - the category of the transaction (choose one from the list below based on the description)
6
+ </context>
7
+
8
+
9
+ <categories>
10
+ The following list contains the categories and associated keywords you often see in transaction descriptions:
11
+ -ATM: atm, cash, withdraw
12
+ -Auto: auto body
13
+ -Bars: bar, pubs, irish, brewery
14
+ -Beauty: body
15
+ -Cashback: cashback, reward, bonus, cash back
16
+ -Clothing: clothing, shoes, accessories
17
+ -Coffee Shops: coffee, cafe, tea, Starbucks, Dunkin
18
+ -Credit Card Payment: card payment, autopay
19
+ -Education: kindle, tuition
20
+ -Entertainment: event, show, movies, cinema, theater
21
+ -Fees: Fee
22
+ -Food: snack, Donalds, Burger King, KFC, Subway, Pizza, Domino, Taco Bell, Wendy, Chick-fil-A, Popeyes, Arby's, Chipotle
23
+ -Fuel: fuel, gas, petrol
24
+ -Gifts: donation, gift
25
+ -Groceries: groceries, supermarket, food, familia
26
+ -Gym: gym, fitness, yoga, pilates, crossfit
27
+ -Home: Ikea
28
+ -Housing: rent, mortgage
29
+ -Income: refund, deposit, paycheck
30
+ -Insurance: insurance
31
+ -Medical: medical, doctor, dentist, hospital, clinic
32
+ -Pets: vet, veterinary, pet, dog, cat
33
+ -Pharmacy: pharmacy, drugstore, cvs, walgreens, rite aid, duane
34
+ -Restaurants: restaurant, lunch, dinner
35
+ -Services: service, laundry, dry cleaning
36
+ -Shopping: shopping, amazon, walmart, target, safeway
37
+ -Streaming: Netflix, Spotify, Hulu, HBO
38
+ -Taxes: tax, irs
39
+ -Technology: technology, software, hardware, electronics
40
+ -Transportation: bus, train, subway, metro, airline, uber, lyft, taxi
41
+ -Travel: travel, holiday, trip, airbnb, kiwi, hotel, hostel, resort, kiwi, kayak, expedia, booking.com
42
+ -Transfer: payment from
43
+ -Utilities: electricity, water, gas, ting, verizon, comcast, sprint, t-mobile, at&t, mint
44
+ -Other: use this when very uncertain about the category
45
+ </categories>
46
+
47
+ <formatting_instructions>
48
+ Your output should be a valid list of lists (e.g. [[description1, category1], [description2, category2], ...]] parse-able by the command ast.literal_eval(output)
49
+ Don't include any kind of commentary, return carriages, spaces or other characters in the output
50
+ Fill all categories; if you don't know which one to choose, choose 'Other'
51
+ </formatting_instructions>
52
+
53
+
54
+ <financial_transactions>
55
+ {input_data}
56
+ </financial_transactions>"""
app/transactions_rag/__init__.py ADDED
File without changes
app/transactions_rag/categorize_transactions.ipynb ADDED
@@ -0,0 +1,572 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 2,
6
+ "metadata": {},
7
+ "outputs": [
8
+ {
9
+ "name": "stdout",
10
+ "output_type": "stream",
11
+ "text": [
12
+ "Defaulting to user installation because normal site-packages is not writeable\n",
13
+ "Requirement already satisfied: pandas in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (2.0.3)\n",
14
+ "Requirement already satisfied: python-dateutil>=2.8.2 in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (from pandas) (2.9.0.post0)\n",
15
+ "Requirement already satisfied: pytz>=2020.1 in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (from pandas) (2024.1)\n",
16
+ "Requirement already satisfied: tzdata>=2022.1 in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (from pandas) (2024.1)\n",
17
+ "Requirement already satisfied: numpy>=1.20.3 in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (from pandas) (1.24.4)\n",
18
+ "Requirement already satisfied: six>=1.5 in /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/site-packages (from python-dateutil>=2.8.2->pandas) (1.15.0)\n"
19
+ ]
20
+ },
21
+ {
22
+ "data": {
23
+ "text/html": [
24
+ "<div>\n",
25
+ "<style scoped>\n",
26
+ " .dataframe tbody tr th:only-of-type {\n",
27
+ " vertical-align: middle;\n",
28
+ " }\n",
29
+ "\n",
30
+ " .dataframe tbody tr th {\n",
31
+ " vertical-align: top;\n",
32
+ " }\n",
33
+ "\n",
34
+ " .dataframe thead th {\n",
35
+ " text-align: right;\n",
36
+ " }\n",
37
+ "</style>\n",
38
+ "<table border=\"1\" class=\"dataframe\">\n",
39
+ " <thead>\n",
40
+ " <tr style=\"text-align: right;\">\n",
41
+ " <th></th>\n",
42
+ " <th>Date</th>\n",
43
+ " <th>Name / Description</th>\n",
44
+ " <th>Expense/Income</th>\n",
45
+ " <th>Amount</th>\n",
46
+ " </tr>\n",
47
+ " </thead>\n",
48
+ " <tbody>\n",
49
+ " <tr>\n",
50
+ " <th>0</th>\n",
51
+ " <td>2023-12-30</td>\n",
52
+ " <td>Comcast Internet</td>\n",
53
+ " <td>Expense</td>\n",
54
+ " <td>9.96</td>\n",
55
+ " </tr>\n",
56
+ " <tr>\n",
57
+ " <th>1</th>\n",
58
+ " <td>2023-12-30</td>\n",
59
+ " <td>Lemonade Home Insurance</td>\n",
60
+ " <td>Expense</td>\n",
61
+ " <td>17.53</td>\n",
62
+ " </tr>\n",
63
+ " <tr>\n",
64
+ " <th>2</th>\n",
65
+ " <td>2023-12-30</td>\n",
66
+ " <td>Monthly Appartment Rent</td>\n",
67
+ " <td>Expense</td>\n",
68
+ " <td>2000.00</td>\n",
69
+ " </tr>\n",
70
+ " <tr>\n",
71
+ " <th>3</th>\n",
72
+ " <td>2023-12-30</td>\n",
73
+ " <td>Staples Office Supplies</td>\n",
74
+ " <td>Expense</td>\n",
75
+ " <td>12.46</td>\n",
76
+ " </tr>\n",
77
+ " <tr>\n",
78
+ " <th>4</th>\n",
79
+ " <td>2023-12-29</td>\n",
80
+ " <td>Selling Paintings</td>\n",
81
+ " <td>Income</td>\n",
82
+ " <td>13.63</td>\n",
83
+ " </tr>\n",
84
+ " </tbody>\n",
85
+ "</table>\n",
86
+ "</div>"
87
+ ],
88
+ "text/plain": [
89
+ " Date Name / Description Expense/Income Amount\n",
90
+ "0 2023-12-30 Comcast Internet Expense 9.96\n",
91
+ "1 2023-12-30 Lemonade Home Insurance Expense 17.53\n",
92
+ "2 2023-12-30 Monthly Appartment Rent Expense 2000.00\n",
93
+ "3 2023-12-30 Staples Office Supplies Expense 12.46\n",
94
+ "4 2023-12-29 Selling Paintings Income 13.63"
95
+ ]
96
+ },
97
+ "execution_count": 2,
98
+ "metadata": {},
99
+ "output_type": "execute_result"
100
+ }
101
+ ],
102
+ "source": [
103
+ "# Read the transactions csv\n",
104
+ "!pip3 install pandas\n",
105
+ "\n",
106
+ "import pandas as pd\n",
107
+ "df = pd.read_csv(\"transactions_2024.csv\")\n",
108
+ "df.head()"
109
+ ]
110
+ },
111
+ {
112
+ "cell_type": "code",
113
+ "execution_count": 3,
114
+ "metadata": {},
115
+ "outputs": [
116
+ {
117
+ "data": {
118
+ "text/plain": [
119
+ "array(['Lemonade Home Insurance', 'Monthly Appartment Rent',\n",
120
+ " 'Staples Office Supplies', 'Selling Paintings', 'Spotify',\n",
121
+ " 'Target', 'IT Consulting', 'Phone', 'ML Consulting'], dtype=object)"
122
+ ]
123
+ },
124
+ "execution_count": 3,
125
+ "metadata": {},
126
+ "output_type": "execute_result"
127
+ }
128
+ ],
129
+ "source": [
130
+ "# Get Unique transactions in the Name/Description column\n",
131
+ "unique_transactions = df[\"Name / Description\"].unique()\n",
132
+ "unique_transactions[1:10]"
133
+ ]
134
+ },
135
+ {
136
+ "cell_type": "code",
137
+ "execution_count": 15,
138
+ "metadata": {},
139
+ "outputs": [],
140
+ "source": [
141
+ "!python3 -m venv venv"
142
+ ]
143
+ },
144
+ {
145
+ "cell_type": "code",
146
+ "execution_count": 16,
147
+ "metadata": {},
148
+ "outputs": [],
149
+ "source": [
150
+ "!source venv/bin/activate"
151
+ ]
152
+ },
153
+ {
154
+ "cell_type": "code",
155
+ "execution_count": 23,
156
+ "metadata": {},
157
+ "outputs": [
158
+ {
159
+ "name": "stdout",
160
+ "output_type": "stream",
161
+ "text": [
162
+ "Defaulting to user installation because normal site-packages is not writeable\n",
163
+ "Requirement already satisfied: setuptools in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (70.0.0)\n"
164
+ ]
165
+ }
166
+ ],
167
+ "source": [
168
+ "!pip3 install --upgrade setuptools"
169
+ ]
170
+ },
171
+ {
172
+ "cell_type": "code",
173
+ "execution_count": 2,
174
+ "metadata": {},
175
+ "outputs": [
176
+ {
177
+ "data": {
178
+ "text/plain": [
179
+ "['Defaulting to user installation because normal site-packages is not writeable',\n",
180
+ " 'Requirement already satisfied: langchain in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (from -r requirements.txt (line 1)) (0.2.1)',\n",
181
+ " 'Collecting langchain_openai (from -r requirements.txt (line 2))',\n",
182
+ " ' Downloading langchain_openai-0.1.7-py3-none-any.whl.metadata (2.5 kB)',\n",
183
+ " 'Collecting python-dotenv (from -r requirements.txt (line 3))',\n",
184
+ " ' Using cached python_dotenv-1.0.1-py3-none-any.whl.metadata (23 kB)',\n",
185
+ " 'Collecting openai (from -r requirements.txt (line 4))',\n",
186
+ " ' Using cached openai-1.30.4-py3-none-any.whl.metadata (21 kB)',\n",
187
+ " 'Requirement already satisfied: tenacity in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (from -r requirements.txt (line 5)) (8.3.0)',\n",
188
+ " 'Requirement already satisfied: rapidfuzz in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (from -r requirements.txt (line 6)) (3.9.1)',\n",
189
+ " 'Requirement already satisfied: pydantic in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (from -r requirements.txt (line 7)) (2.7.1)',\n",
190
+ " 'Requirement already satisfied: dateparser in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (from -r requirements.txt (line 8)) (1.2.0)',\n",
191
+ " 'Requirement already satisfied: pandas in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (from -r requirements.txt (line 9)) (2.0.3)',\n",
192
+ " 'Collecting path (from -r requirements.txt (line 10))',\n",
193
+ " ' Using cached path-16.14.0-py3-none-any.whl.metadata (6.3 kB)',\n",
194
+ " 'Collecting aiostream==0.5.2 (from -r requirements.txt (line 12))',\n",
195
+ " ' Using cached aiostream-0.5.2-py3-none-any.whl.metadata (9.9 kB)',\n",
196
+ " 'Collecting cachetools==5.3.3 (from -r requirements.txt (line 13))',\n",
197
+ " ' Using cached cachetools-5.3.3-py3-none-any.whl.metadata (5.3 kB)',\n",
198
+ " 'Collecting docx2txt==0.8 (from -r requirements.txt (line 14))',\n",
199
+ " ' Using cached docx2txt-0.8.tar.gz (2.8 kB)',\n",
200
+ " ' Preparing metadata (setup.py): started',\n",
201
+ " \" Preparing metadata (setup.py): finished with status 'done'\",\n",
202
+ " 'Collecting fastapi==0.109.1 (from -r requirements.txt (line 15))',\n",
203
+ " ' Using cached fastapi-0.109.1-py3-none-any.whl.metadata (25 kB)',\n",
204
+ " 'Collecting llama-index-agent-openai==0.2.2 (from -r requirements.txt (line 16))',\n",
205
+ " ' Using cached llama_index_agent_openai-0.2.2-py3-none-any.whl.metadata (677 bytes)',\n",
206
+ " 'Collecting llama-index-core==0.10.28 (from -r requirements.txt (line 17))',\n",
207
+ " ' Using cached llama_index_core-0.10.28-py3-none-any.whl.metadata (3.6 kB)',\n",
208
+ " 'Collecting llama-index-vector-stores-pinecone==0.1.3 (from -r requirements.txt (line 18))',\n",
209
+ " ' Using cached llama_index_vector_stores_pinecone-0.1.3-py3-none-any.whl.metadata (725 bytes)',\n",
210
+ " 'Collecting llama-index==0.10.28 (from -r requirements.txt (line 19))',\n",
211
+ " ' Using cached llama_index-0.10.28-py3-none-any.whl.metadata (11 kB)',\n",
212
+ " 'Collecting python-dotenv (from -r requirements.txt (line 3))',\n",
213
+ " ' Using cached python_dotenv-1.0.0-py3-none-any.whl.metadata (21 kB)',\n",
214
+ " '\\x1b[31mERROR: Ignored the following versions that require a different python version: 0.0.10 Requires-Python >=3.9,<4.0; 0.0.11 Requires-Python >=3.9,<4.0; 0.0.12 Requires-Python >=3.9,<4.0; 0.0.13 Requires-Python >=3.9,<4.0; 0.0.14 Requires-Python >=3.9,<4.0; 0.0.15 Requires-Python >=3.9,<4.0; 0.0.16 Requires-Python >=3.9,<4.0; 0.0.17 Requires-Python >=3.9,<4.0; 0.0.18 Requires-Python >=3.9,<4.0; 0.0.19 Requires-Python >=3.9,<4.0; 0.0.20 Requires-Python >=3.9,<4.0; 0.0.21 Requires-Python >=3.9,<4.0; 0.0.22 Requires-Python >=3.9,<4.0; 0.0.23 Requires-Python >=3.9,<4.0; 0.0.24 Requires-Python >=3.9,<4.0; 0.0.25 Requires-Python >=3.9,<4.0; 0.14.3 Requires-Python >=3.9,<4; 0.14.4 Requires-Python <4,>=3.9; 0.14.5 Requires-Python <4,>=3.9; 0.15.0 Requires-Python <4,>=3.9; 0.15.1 Requires-Python <4,>=3.9; 0.15.10 Requires-Python <4,>=3.9; 0.15.11 Requires-Python <4,>=3.9; 0.15.12 Requires-Python <4,>=3.9; 0.15.13 Requires-Python <4,>=3.9; 0.15.2 Requires-Python <4,>=3.9; 0.15.3 Requires-Python <4,>=3.9; 0.15.4 Requires-Python <4,>=3.9; 0.15.5 Requires-Python <4,>=3.9; 0.15.6 Requires-Python <4,>=3.9; 0.15.7 Requires-Python <4,>=3.9; 0.15.8 Requires-Python <4,>=3.9; 0.15.9 Requires-Python <4,>=3.9; 0.16.0 Requires-Python <4,>=3.9; 0.16.1 Requires-Python <4,>=3.9; 0.16.2 Requires-Python <4,>=3.9; 0.16.3 Requires-Python <4,>=3.9; 0.16.4 Requires-Python <4,>=3.9; 0.16.5 Requires-Python <4,>=3.9; 0.16.6 Requires-Python <4,>=3.9; 0.16.7 Requires-Python <4,>=3.9; 0.16.8 Requires-Python <4,>=3.9; 0.16.9 Requires-Python <4,>=3.9; 0.17.0 Requires-Python <4,>=3.9; 0.17.1 Requires-Python <4,>=3.9; 0.17.2 Requires-Python <4,>=3.9; 0.17.3 Requires-Python <4,>=3.9; 0.17.4 Requires-Python <4,>=3.9; 0.17.5 Requires-Python <4,>=3.9; 0.17.6 Requires-Python <4,>=3.9; 0.17.7 Requires-Python <4,>=3.9; 0.18.0 Requires-Python <4,>=3.9; 0.18.1 Requires-Python <4,>=3.9; 0.18.2 Requires-Python <4,>=3.9; 0.19.0 Requires-Python <4,>=3.9; 0.20.0 Requires-Python <4,>=3.9; 0.21.0 Requires-Python <4,>=3.9\\x1b[0m\\x1b[31m',\n",
215
+ " '\\x1b[0m\\x1b[31mERROR: Could not find a version that satisfies the requirement traceloop-sdk==0.15.11 (from versions: 0.0.26, 0.0.27b0, 0.0.27, 0.0.28, 0.0.29, 0.0.31, 0.0.32, 0.0.33, 0.0.34, 0.0.35, 0.0.36, 0.0.37, 0.0.38, 0.0.39, 0.0.40, 0.0.41, 0.0.42, 0.0.43b0, 0.0.43b2, 0.0.43b3, 0.0.43b4, 0.0.43, 0.0.44b0, 0.0.44, 0.0.46, 0.0.47, 0.0.48, 0.0.49, 0.0.50, 0.0.51, 0.0.52, 0.0.53, 0.0.54, 0.0.55, 0.0.56a0, 0.0.56a1, 0.0.56a2, 0.0.56a3, 0.0.56a4, 0.0.56a5, 0.0.56a6, 0.0.56, 0.0.57, 0.0.58, 0.0.59, 0.0.60a0, 0.0.60a1, 0.0.60, 0.0.61a0, 0.0.61, 0.0.62, 0.0.63, 0.0.64a0, 0.0.64, 0.0.65, 0.0.66, 0.0.67, 0.0.68, 0.0.69, 0.0.70, 0.1.3, 0.1.5, 0.1.6, 0.1.7, 0.1.8, 0.1.9, 0.1.10, 0.1.11, 0.1.12, 0.2.0, 0.2.1, 0.3.0, 0.3.1, 0.3.2, 0.3.3, 0.3.4, 0.3.5, 0.3.6, 0.4.0, 0.4.1, 0.4.2, 0.5.0, 0.5.1, 0.5.2, 0.5.3, 0.6.0, 0.7.0, 0.8.0, 0.8.2, 0.9.0, 0.9.1, 0.9.2, 0.9.3, 0.9.4, 0.10.0, 0.10.1, 0.10.2, 0.10.3, 0.10.4, 0.10.5, 0.11.0, 0.11.1, 0.11.2, 0.11.3, 0.12.0, 0.12.1, 0.12.2, 0.12.3, 0.12.4, 0.12.5, 0.13.0, 0.13.1, 0.13.2, 0.13.3, 0.14.0, 0.14.1, 0.14.2)\\x1b[0m\\x1b[31m',\n",
216
+ " '\\x1b[0m\\x1b[31mERROR: No matching distribution found for traceloop-sdk==0.15.11\\x1b[0m\\x1b[31m',\n",
217
+ " '\\x1b[0m']"
218
+ ]
219
+ },
220
+ "execution_count": 2,
221
+ "metadata": {},
222
+ "output_type": "execute_result"
223
+ }
224
+ ],
225
+ "source": [
226
+ "!!pip3 install -r requirements.txt"
227
+ ]
228
+ },
229
+ {
230
+ "cell_type": "code",
231
+ "execution_count": 28,
232
+ "metadata": {},
233
+ "outputs": [
234
+ {
235
+ "name": "stdout",
236
+ "output_type": "stream",
237
+ "text": [
238
+ "Defaulting to user installation because normal site-packages is not writeable\n",
239
+ "Collecting dateparser\n",
240
+ " Using cached dateparser-1.2.0-py2.py3-none-any.whl.metadata (28 kB)\n",
241
+ "Requirement already satisfied: python-dateutil in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (from dateparser) (2.9.0.post0)\n",
242
+ "Requirement already satisfied: pytz in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (from dateparser) (2024.1)\n",
243
+ "Collecting regex!=2019.02.19,!=2021.8.27 (from dateparser)\n",
244
+ " Downloading regex-2024.5.15-cp38-cp38-macosx_10_9_x86_64.whl.metadata (40 kB)\n",
245
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m40.9/40.9 kB\u001b[0m \u001b[31m95.7 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0ma \u001b[36m0:00:01\u001b[0m\n",
246
+ "\u001b[?25hCollecting tzlocal (from dateparser)\n",
247
+ " Downloading tzlocal-5.2-py3-none-any.whl.metadata (7.8 kB)\n",
248
+ "Requirement already satisfied: six>=1.5 in /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/site-packages (from python-dateutil->dateparser) (1.15.0)\n",
249
+ "Collecting backports.zoneinfo (from tzlocal->dateparser)\n",
250
+ " Downloading backports.zoneinfo-0.2.1-cp38-cp38-macosx_10_14_x86_64.whl.metadata (4.7 kB)\n",
251
+ "Downloading dateparser-1.2.0-py2.py3-none-any.whl (294 kB)\n",
252
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m295.0/295.0 kB\u001b[0m \u001b[31m510.0 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0ma \u001b[36m0:00:01\u001b[0m\n",
253
+ "\u001b[?25hDownloading regex-2024.5.15-cp38-cp38-macosx_10_9_x86_64.whl (281 kB)\n",
254
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m281.8/281.8 kB\u001b[0m \u001b[31m2.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n",
255
+ "\u001b[?25hDownloading tzlocal-5.2-py3-none-any.whl (17 kB)\n",
256
+ "Downloading backports.zoneinfo-0.2.1-cp38-cp38-macosx_10_14_x86_64.whl (35 kB)\n",
257
+ "Installing collected packages: regex, backports.zoneinfo, tzlocal, dateparser\n",
258
+ "\u001b[33m WARNING: The script dateparser-download is installed in '/Users/patrickalexis/Library/Python/3.8/bin' which is not on PATH.\n",
259
+ " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\u001b[0m\u001b[33m\n",
260
+ "\u001b[0mSuccessfully installed backports.zoneinfo-0.2.1 dateparser-1.2.0 regex-2024.5.15 tzlocal-5.2\n"
261
+ ]
262
+ }
263
+ ],
264
+ "source": [
265
+ "!pip3 install dateparser"
266
+ ]
267
+ },
268
+ {
269
+ "cell_type": "code",
270
+ "execution_count": 2,
271
+ "metadata": {},
272
+ "outputs": [
273
+ {
274
+ "name": "stdout",
275
+ "output_type": "stream",
276
+ "text": [
277
+ "Defaulting to user installation because normal site-packages is not writeable\n",
278
+ "Collecting rapidfuzz\n",
279
+ " Using cached rapidfuzz-3.9.1-cp38-cp38-macosx_10_9_x86_64.whl.metadata (11 kB)\n",
280
+ "Using cached rapidfuzz-3.9.1-cp38-cp38-macosx_10_9_x86_64.whl (2.1 MB)\n",
281
+ "Installing collected packages: rapidfuzz\n",
282
+ "Successfully installed rapidfuzz-3.9.1\n"
283
+ ]
284
+ }
285
+ ],
286
+ "source": [
287
+ "!pip3 install rapidfuzz"
288
+ ]
289
+ },
290
+ {
291
+ "cell_type": "code",
292
+ "execution_count": 2,
293
+ "metadata": {},
294
+ "outputs": [
295
+ {
296
+ "name": "stdout",
297
+ "output_type": "stream",
298
+ "text": [
299
+ "Defaulting to user installation because normal site-packages is not writeable\n",
300
+ "Collecting dotenv\n",
301
+ " Downloading dotenv-0.0.5.tar.gz (2.4 kB)\n",
302
+ " Preparing metadata (setup.py) ... \u001b[?25lerror\n",
303
+ " \u001b[1;31merror\u001b[0m: \u001b[1msubprocess-exited-with-error\u001b[0m\n",
304
+ " \n",
305
+ " \u001b[31m×\u001b[0m \u001b[32mpython setup.py egg_info\u001b[0m did not run successfully.\n",
306
+ " \u001b[31m│\u001b[0m exit code: \u001b[1;36m1\u001b[0m\n",
307
+ " \u001b[31m╰─>\u001b[0m \u001b[31m[76 lines of output]\u001b[0m\n",
308
+ " \u001b[31m \u001b[0m /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages/setuptools/__init__.py:80: _DeprecatedInstaller: setuptools.installer and fetch_build_eggs are deprecated.\n",
309
+ " \u001b[31m \u001b[0m !!\n",
310
+ " \u001b[31m \u001b[0m \n",
311
+ " \u001b[31m \u001b[0m ********************************************************************************\n",
312
+ " \u001b[31m \u001b[0m Requirements should be satisfied by a PEP 517 installer.\n",
313
+ " \u001b[31m \u001b[0m If you are using pip, you can try `pip install --use-pep517`.\n",
314
+ " \u001b[31m \u001b[0m ********************************************************************************\n",
315
+ " \u001b[31m \u001b[0m \n",
316
+ " \u001b[31m \u001b[0m !!\n",
317
+ " \u001b[31m \u001b[0m dist.fetch_build_eggs(dist.setup_requires)\n",
318
+ " \u001b[31m \u001b[0m \u001b[1;31merror\u001b[0m: \u001b[1msubprocess-exited-with-error\u001b[0m\n",
319
+ " \u001b[31m \u001b[0m \n",
320
+ " \u001b[31m \u001b[0m \u001b[31m×\u001b[0m \u001b[32mpython setup.py egg_info\u001b[0m did not run successfully.\n",
321
+ " \u001b[31m \u001b[0m \u001b[31m│\u001b[0m exit code: \u001b[1;36m1\u001b[0m\n",
322
+ " \u001b[31m \u001b[0m \u001b[31m╰─>\u001b[0m \u001b[31m[16 lines of output]\u001b[0m\n",
323
+ " \u001b[31m \u001b[0m \u001b[31m \u001b[0m Traceback (most recent call last):\n",
324
+ " \u001b[31m \u001b[0m \u001b[31m \u001b[0m File \"<string>\", line 2, in <module>\n",
325
+ " \u001b[31m \u001b[0m \u001b[31m \u001b[0m File \"<pip-setuptools-caller>\", line 14, in <module>\n",
326
+ " \u001b[31m \u001b[0m \u001b[31m \u001b[0m File \"/private/var/folders/g9/flbt409n1b7g0ry4b9ffdvnc0000gn/T/pip-wheel-66v7g1h6/distribute_6e0b47b8750a4aa8bfff62a3f867a97f/setuptools/__init__.py\", line 2, in <module>\n",
327
+ " \u001b[31m \u001b[0m \u001b[31m \u001b[0m from setuptools.extension import Extension, Library\n",
328
+ " \u001b[31m \u001b[0m \u001b[31m \u001b[0m File \"/private/var/folders/g9/flbt409n1b7g0ry4b9ffdvnc0000gn/T/pip-wheel-66v7g1h6/distribute_6e0b47b8750a4aa8bfff62a3f867a97f/setuptools/extension.py\", line 5, in <module>\n",
329
+ " \u001b[31m \u001b[0m \u001b[31m \u001b[0m from setuptools.dist import _get_unpatched\n",
330
+ " \u001b[31m \u001b[0m \u001b[31m \u001b[0m File \"/private/var/folders/g9/flbt409n1b7g0ry4b9ffdvnc0000gn/T/pip-wheel-66v7g1h6/distribute_6e0b47b8750a4aa8bfff62a3f867a97f/setuptools/dist.py\", line 7, in <module>\n",
331
+ " \u001b[31m \u001b[0m \u001b[31m \u001b[0m from setuptools.command.install import install\n",
332
+ " \u001b[31m \u001b[0m \u001b[31m \u001b[0m File \"/private/var/folders/g9/flbt409n1b7g0ry4b9ffdvnc0000gn/T/pip-wheel-66v7g1h6/distribute_6e0b47b8750a4aa8bfff62a3f867a97f/setuptools/command/__init__.py\", line 8, in <module>\n",
333
+ " \u001b[31m \u001b[0m \u001b[31m \u001b[0m from setuptools.command import install_scripts\n",
334
+ " \u001b[31m \u001b[0m \u001b[31m \u001b[0m File \"/private/var/folders/g9/flbt409n1b7g0ry4b9ffdvnc0000gn/T/pip-wheel-66v7g1h6/distribute_6e0b47b8750a4aa8bfff62a3f867a97f/setuptools/command/install_scripts.py\", line 3, in <module>\n",
335
+ " \u001b[31m \u001b[0m \u001b[31m \u001b[0m from pkg_resources import Distribution, PathMetadata, ensure_directory\n",
336
+ " \u001b[31m \u001b[0m \u001b[31m \u001b[0m File \"/private/var/folders/g9/flbt409n1b7g0ry4b9ffdvnc0000gn/T/pip-wheel-66v7g1h6/distribute_6e0b47b8750a4aa8bfff62a3f867a97f/pkg_resources.py\", line 1518, in <module>\n",
337
+ " \u001b[31m \u001b[0m \u001b[31m \u001b[0m register_loader_type(importlib_bootstrap.SourceFileLoader, DefaultProvider)\n",
338
+ " \u001b[31m \u001b[0m \u001b[31m \u001b[0m AttributeError: module 'importlib._bootstrap' has no attribute 'SourceFileLoader'\n",
339
+ " \u001b[31m \u001b[0m \u001b[31m \u001b[0m \u001b[31m[end of output]\u001b[0m\n",
340
+ " \u001b[31m \u001b[0m \n",
341
+ " \u001b[31m \u001b[0m \u001b[1;35mnote\u001b[0m: This error originates from a subprocess, and is likely not a problem with pip.\n",
342
+ " \u001b[31m \u001b[0m \u001b[1;31merror\u001b[0m: \u001b[1mmetadata-generation-failed\u001b[0m\n",
343
+ " \u001b[31m \u001b[0m \n",
344
+ " \u001b[31m \u001b[0m \u001b[31m×\u001b[0m Encountered error while generating package metadata.\n",
345
+ " \u001b[31m \u001b[0m \u001b[31m╰─>\u001b[0m See above for output.\n",
346
+ " \u001b[31m \u001b[0m \n",
347
+ " \u001b[31m \u001b[0m \u001b[1;35mnote\u001b[0m: This is an issue with the package mentioned above, not pip.\n",
348
+ " \u001b[31m \u001b[0m \u001b[1;36mhint\u001b[0m: See above for details.\n",
349
+ " \u001b[31m \u001b[0m Traceback (most recent call last):\n",
350
+ " \u001b[31m \u001b[0m File \"/Users/patrickalexis/Library/Python/3.8/lib/python/site-packages/setuptools/installer.py\", line 101, in _fetch_build_egg_no_warn\n",
351
+ " \u001b[31m \u001b[0m subprocess.check_call(cmd)\n",
352
+ " \u001b[31m \u001b[0m File \"/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/subprocess.py\", line 364, in check_call\n",
353
+ " \u001b[31m \u001b[0m raise CalledProcessError(retcode, cmd)\n",
354
+ " \u001b[31m \u001b[0m subprocess.CalledProcessError: Command '['/Applications/Xcode.app/Contents/Developer/usr/bin/python3', '-m', 'pip', '--disable-pip-version-check', 'wheel', '--no-deps', '-w', '/var/folders/g9/flbt409n1b7g0ry4b9ffdvnc0000gn/T/tmpnw2yadh3', '--quiet', 'distribute']' returned non-zero exit status 1.\n",
355
+ " \u001b[31m \u001b[0m \n",
356
+ " \u001b[31m \u001b[0m The above exception was the direct cause of the following exception:\n",
357
+ " \u001b[31m \u001b[0m \n",
358
+ " \u001b[31m \u001b[0m Traceback (most recent call last):\n",
359
+ " \u001b[31m \u001b[0m File \"<string>\", line 2, in <module>\n",
360
+ " \u001b[31m \u001b[0m File \"<pip-setuptools-caller>\", line 34, in <module>\n",
361
+ " \u001b[31m \u001b[0m File \"/private/var/folders/g9/flbt409n1b7g0ry4b9ffdvnc0000gn/T/pip-install-ac3_ml88/dotenv_7766945cfd7d4e62965375b30e9a0c21/setup.py\", line 13, in <module>\n",
362
+ " \u001b[31m \u001b[0m setup(name='dotenv',\n",
363
+ " \u001b[31m \u001b[0m File \"/Users/patrickalexis/Library/Python/3.8/lib/python/site-packages/setuptools/__init__.py\", line 102, in setup\n",
364
+ " \u001b[31m \u001b[0m _install_setup_requires(attrs)\n",
365
+ " \u001b[31m \u001b[0m File \"/Users/patrickalexis/Library/Python/3.8/lib/python/site-packages/setuptools/__init__.py\", line 75, in _install_setup_requires\n",
366
+ " \u001b[31m \u001b[0m _fetch_build_eggs(dist)\n",
367
+ " \u001b[31m \u001b[0m File \"/Users/patrickalexis/Library/Python/3.8/lib/python/site-packages/setuptools/__init__.py\", line 80, in _fetch_build_eggs\n",
368
+ " \u001b[31m \u001b[0m dist.fetch_build_eggs(dist.setup_requires)\n",
369
+ " \u001b[31m \u001b[0m File \"/Users/patrickalexis/Library/Python/3.8/lib/python/site-packages/setuptools/dist.py\", line 641, in fetch_build_eggs\n",
370
+ " \u001b[31m \u001b[0m return _fetch_build_eggs(self, requires)\n",
371
+ " \u001b[31m \u001b[0m File \"/Users/patrickalexis/Library/Python/3.8/lib/python/site-packages/setuptools/installer.py\", line 38, in _fetch_build_eggs\n",
372
+ " \u001b[31m \u001b[0m resolved_dists = pkg_resources.working_set.resolve(\n",
373
+ " \u001b[31m \u001b[0m File \"/Users/patrickalexis/Library/Python/3.8/lib/python/site-packages/pkg_resources/__init__.py\", line 787, in resolve\n",
374
+ " \u001b[31m \u001b[0m dist = self._resolve_dist(\n",
375
+ " \u001b[31m \u001b[0m File \"/Users/patrickalexis/Library/Python/3.8/lib/python/site-packages/pkg_resources/__init__.py\", line 823, in _resolve_dist\n",
376
+ " \u001b[31m \u001b[0m dist = best[req.key] = env.best_match(\n",
377
+ " \u001b[31m \u001b[0m File \"/Users/patrickalexis/Library/Python/3.8/lib/python/site-packages/pkg_resources/__init__.py\", line 1093, in best_match\n",
378
+ " \u001b[31m \u001b[0m return self.obtain(req, installer)\n",
379
+ " \u001b[31m \u001b[0m File \"/Users/patrickalexis/Library/Python/3.8/lib/python/site-packages/pkg_resources/__init__.py\", line 1104, in obtain\n",
380
+ " \u001b[31m \u001b[0m return installer(requirement) if installer else None\n",
381
+ " \u001b[31m \u001b[0m File \"/Users/patrickalexis/Library/Python/3.8/lib/python/site-packages/setuptools/installer.py\", line 103, in _fetch_build_egg_no_warn\n",
382
+ " \u001b[31m \u001b[0m raise DistutilsError(str(e)) from e\n",
383
+ " \u001b[31m \u001b[0m distutils.errors.DistutilsError: Command '['/Applications/Xcode.app/Contents/Developer/usr/bin/python3', '-m', 'pip', '--disable-pip-version-check', 'wheel', '--no-deps', '-w', '/var/folders/g9/flbt409n1b7g0ry4b9ffdvnc0000gn/T/tmpnw2yadh3', '--quiet', 'distribute']' returned non-zero exit status 1.\n",
384
+ " \u001b[31m \u001b[0m \u001b[31m[end of output]\u001b[0m\n",
385
+ " \n",
386
+ " \u001b[1;35mnote\u001b[0m: This error originates from a subprocess, and is likely not a problem with pip.\n",
387
+ "\u001b[?25h\u001b[1;31merror\u001b[0m: \u001b[1mmetadata-generation-failed\u001b[0m\n",
388
+ "\n",
389
+ "\u001b[31m×\u001b[0m Encountered error while generating package metadata.\n",
390
+ "\u001b[31m╰─>\u001b[0m See above for output.\n",
391
+ "\n",
392
+ "\u001b[1;35mnote\u001b[0m: This is an issue with the package mentioned above, not pip.\n",
393
+ "\u001b[1;36mhint\u001b[0m: See above for details.\n"
394
+ ]
395
+ }
396
+ ],
397
+ "source": [
398
+ "!pip3 install dotenv"
399
+ ]
400
+ },
401
+ {
402
+ "cell_type": "code",
403
+ "execution_count": 10,
404
+ "metadata": {},
405
+ "outputs": [],
406
+ "source": [
407
+ "# Create data folder\n",
408
+ "!mkdir -p data/tx_data/output\n",
409
+ "!mkdir -p data/ref_data"
410
+ ]
411
+ },
412
+ {
413
+ "cell_type": "code",
414
+ "execution_count": 4,
415
+ "metadata": {},
416
+ "outputs": [
417
+ {
418
+ "name": "stdout",
419
+ "output_type": "stream",
420
+ "text": [
421
+ "Defaulting to user installation because normal site-packages is not writeable\n",
422
+ "Collecting openai\n",
423
+ " Using cached openai-1.30.4-py3-none-any.whl.metadata (21 kB)\n",
424
+ "Collecting anyio<5,>=3.5.0 (from openai)\n",
425
+ " Downloading anyio-4.4.0-py3-none-any.whl.metadata (4.6 kB)\n",
426
+ "Collecting distro<2,>=1.7.0 (from openai)\n",
427
+ " Downloading distro-1.9.0-py3-none-any.whl.metadata (6.8 kB)\n",
428
+ "Collecting httpx<1,>=0.23.0 (from openai)\n",
429
+ " Downloading httpx-0.27.0-py3-none-any.whl.metadata (7.2 kB)\n",
430
+ "Requirement already satisfied: pydantic<3,>=1.9.0 in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (from openai) (2.7.1)\n",
431
+ "Collecting sniffio (from openai)\n",
432
+ " Downloading sniffio-1.3.1-py3-none-any.whl.metadata (3.9 kB)\n",
433
+ "Requirement already satisfied: tqdm>4 in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (from openai) (4.66.4)\n",
434
+ "Requirement already satisfied: typing-extensions<5,>=4.7 in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (from openai) (4.12.0)\n",
435
+ "Requirement already satisfied: idna>=2.8 in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (from anyio<5,>=3.5.0->openai) (3.7)\n",
436
+ "Collecting exceptiongroup>=1.0.2 (from anyio<5,>=3.5.0->openai)\n",
437
+ " Downloading exceptiongroup-1.2.1-py3-none-any.whl.metadata (6.6 kB)\n",
438
+ "Requirement already satisfied: certifi in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (from httpx<1,>=0.23.0->openai) (2024.2.2)\n",
439
+ "Collecting httpcore==1.* (from httpx<1,>=0.23.0->openai)\n",
440
+ " Downloading httpcore-1.0.5-py3-none-any.whl.metadata (20 kB)\n",
441
+ "Collecting h11<0.15,>=0.13 (from httpcore==1.*->httpx<1,>=0.23.0->openai)\n",
442
+ " Downloading h11-0.14.0-py3-none-any.whl.metadata (8.2 kB)\n",
443
+ "Requirement already satisfied: annotated-types>=0.4.0 in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (from pydantic<3,>=1.9.0->openai) (0.7.0)\n",
444
+ "Requirement already satisfied: pydantic-core==2.18.2 in /Users/patrickalexis/Library/Python/3.8/lib/python/site-packages (from pydantic<3,>=1.9.0->openai) (2.18.2)\n",
445
+ "Downloading openai-1.30.4-py3-none-any.whl (320 kB)\n",
446
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m320.6/320.6 kB\u001b[0m \u001b[31m5.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n",
447
+ "\u001b[?25hDownloading anyio-4.4.0-py3-none-any.whl (86 kB)\n",
448
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m86.8/86.8 kB\u001b[0m \u001b[31m3.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
449
+ "\u001b[?25hDownloading distro-1.9.0-py3-none-any.whl (20 kB)\n",
450
+ "Downloading httpx-0.27.0-py3-none-any.whl (75 kB)\n",
451
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m75.6/75.6 kB\u001b[0m \u001b[31m2.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
452
+ "\u001b[?25hDownloading httpcore-1.0.5-py3-none-any.whl (77 kB)\n",
453
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m77.9/77.9 kB\u001b[0m \u001b[31m4.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
454
+ "\u001b[?25hDownloading sniffio-1.3.1-py3-none-any.whl (10 kB)\n",
455
+ "Downloading exceptiongroup-1.2.1-py3-none-any.whl (16 kB)\n",
456
+ "Downloading h11-0.14.0-py3-none-any.whl (58 kB)\n",
457
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m2.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
458
+ "\u001b[?25hInstalling collected packages: sniffio, h11, exceptiongroup, distro, httpcore, anyio, httpx, openai\n",
459
+ "\u001b[33m WARNING: The script distro is installed in '/Users/patrickalexis/Library/Python/3.8/bin' which is not on PATH.\n",
460
+ " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\u001b[0m\u001b[33m\n",
461
+ "\u001b[0m\u001b[33m WARNING: The script httpx is installed in '/Users/patrickalexis/Library/Python/3.8/bin' which is not on PATH.\n",
462
+ " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\u001b[0m\u001b[33m\n",
463
+ "\u001b[0m\u001b[33m WARNING: The script openai is installed in '/Users/patrickalexis/Library/Python/3.8/bin' which is not on PATH.\n",
464
+ " Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\u001b[0m\u001b[33m\n",
465
+ "\u001b[0mSuccessfully installed anyio-4.4.0 distro-1.9.0 exceptiongroup-1.2.1 h11-0.14.0 httpcore-1.0.5 httpx-0.27.0 openai-1.30.4 sniffio-1.3.1\n"
466
+ ]
467
+ }
468
+ ],
469
+ "source": [
470
+ "!pip3 install openai"
471
+ ]
472
+ },
473
+ {
474
+ "cell_type": "code",
475
+ "execution_count": 5,
476
+ "metadata": {},
477
+ "outputs": [
478
+ {
479
+ "name": "stdout",
480
+ "output_type": "stream",
481
+ "text": [
482
+ "\n",
483
+ "Processing file\n"
484
+ ]
485
+ },
486
+ {
487
+ "name": "stderr",
488
+ "output_type": "stream",
489
+ "text": [
490
+ "ERROR:root:| File: transactions_2024.csv | Unexpected Error: expected str, got module\n"
491
+ ]
492
+ },
493
+ {
494
+ "name": "stdout",
495
+ "output_type": "stream",
496
+ "text": [
497
+ "ERROR processing file transactions_2024.csv: expected str, got module\n",
498
+ "\n",
499
+ "Processed 1 files: 0 successful, 1 with errors\n",
500
+ "\n",
501
+ "Errors in the following files:\n",
502
+ " transactions_2024.csv: expected str, got module\n",
503
+ "\n",
504
+ "\n",
505
+ "[{'file_name': 'transactions_2024.csv', 'output': Empty DataFrame\n",
506
+ "Columns: []\n",
507
+ "Index: [], 'error': 'expected str, got module'}]\n",
508
+ "['name/description,category\\n']\n",
509
+ "None\n"
510
+ ]
511
+ }
512
+ ],
513
+ "source": [
514
+ "# Process the transactions csv and get the results from the categorization llm utility\n",
515
+ "from app.categorization.file_processing import process_file, save_results\n",
516
+ "from app.categorization.config import CATEGORY_REFERENCE_OUTPUT_FILE\n",
517
+ "# from dotenv import load_dotenv\n",
518
+ "import asyncio\n",
519
+ "import os.path\n",
520
+ "\n",
521
+ "# load_dotenv()\n",
522
+ "\n",
523
+ "# relative_dir = os.path.dirname(__file__)\n",
524
+ "# abs_file_path = os.path.join(relative_dir, CATEGORY_REFERENCE_OUTPUT_FILE)\n",
525
+ "\n",
526
+ "async def apply_categorization():\n",
527
+ " processed_file = process_file(\"app/transactions_rag/transactions_2024.csv\")\n",
528
+ "\n",
529
+ " print(\"\\nProcessing file\")\n",
530
+ " result = await asyncio.gather(processed_file)\n",
531
+ "\n",
532
+ " save_results(result)\n",
533
+ " print(result)\n",
534
+ "\n",
535
+ " output_file = open(CATEGORY_REFERENCE_OUTPUT_FILE, \"r+\")\n",
536
+ " print(output_file.readlines())\n",
537
+ "\n",
538
+ "\n",
539
+ "result = await apply_categorization()\n",
540
+ "print(result)\n",
541
+ "\n"
542
+ ]
543
+ }
544
+ ],
545
+ "metadata": {
546
+ "kernelspec": {
547
+ "display_name": "Python 3.8.9 64-bit",
548
+ "language": "python",
549
+ "name": "python3"
550
+ },
551
+ "language_info": {
552
+ "codemirror_mode": {
553
+ "name": "ipython",
554
+ "version": 3
555
+ },
556
+ "file_extension": ".py",
557
+ "mimetype": "text/x-python",
558
+ "name": "python",
559
+ "nbconvert_exporter": "python",
560
+ "pygments_lexer": "ipython3",
561
+ "version": "3.8.9"
562
+ },
563
+ "orig_nbformat": 4,
564
+ "vscode": {
565
+ "interpreter": {
566
+ "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
567
+ }
568
+ }
569
+ },
570
+ "nbformat": 4,
571
+ "nbformat_minor": 2
572
+ }
app/transactions_rag/transactions_2024.csv ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Date,Name / Description,Expense/Income,Amount
2
+ 2023-12-30,Comcast Internet,Expense,9.96
3
+ 2023-12-30,Lemonade Home Insurance,Expense,17.53
4
+ 2023-12-30,Monthly Appartment Rent,Expense,2000.0
5
+ 2023-12-30,Staples Office Supplies,Expense,12.46
6
+ 2023-12-29,Selling Paintings,Income,13.63
7
+ 2023-12-29,Spotify,Expense,12.19
8
+ 2023-12-23,Target,Expense,27.08
9
+ 2023-12-22,IT Consulting,Income,541.57
10
+ 2023-12-22,Phone,Expense,10.7
11
+ 2023-12-20,ML Consulting,Income,2641.93
12
+ 2023-12-19,Chipotle,Expense,18.9
13
+ 2023-12-18,Cold Brew Coffee,Expense,17.67
14
+ 2023-12-18,Gas,Expense,8.80
15
+ 2023-12-18,CA Property Tax,Expense,1670.34
16
+ 2022-11-26,Salary,Income,4000.36
17
+ 2022-11-26,Cellphone,Expense,19.27
18
+ 2022-11-26,Gym Membership,Expense,24.71
19
+ 2022-11-25,Wholefoods,Expense,17.35
20
+ 2022-11-24,Freelancing,Income,2409.55
21
+ 2022-11-19,Spotify,Expense,20.76
22
+ 2022-10-25,Blogging,Income,4044.27
23
+ 2022-10-24,Uber Taxi,Expense,18.9
24
+ 2022-10-23,Uber Taxi,Expense,27.54
25
+ 2022-10-22,Apple Services,Expense,41.25
26
+ 2022-10-21,Netflix,Expense,22.8
27
+ 2022-01-16,Amazon Lux,Expense,24.11
28
+ 2022-01-15,Burger King,Expense,30.08
29
+ 2022-01-14,Amazon,Expense,11.0
poetry.lock CHANGED
@@ -380,6 +380,28 @@ files = [
380
  marshmallow = ">=3.18.0,<4.0.0"
381
  typing-inspect = ">=0.4.0,<1"
382
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
383
  [[package]]
384
  name = "deprecated"
385
  version = "1.2.14"
@@ -1001,6 +1023,139 @@ files = [
1001
  {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"},
1002
  ]
1003
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1004
  [[package]]
1005
  name = "llama-index"
1006
  version = "0.10.28"
@@ -1620,13 +1775,13 @@ files = [
1620
 
1621
  [[package]]
1622
  name = "openai"
1623
- version = "1.30.1"
1624
  description = "The official Python library for the openai API"
1625
  optional = false
1626
  python-versions = ">=3.7.1"
1627
  files = [
1628
- {file = "openai-1.30.1-py3-none-any.whl", hash = "sha256:c9fb3c3545c118bbce8deb824397b9433a66d0d0ede6a96f7009c95b76de4a46"},
1629
- {file = "openai-1.30.1.tar.gz", hash = "sha256:4f85190e577cba0b066e1950b8eb9b11d25bc7ebcc43a86b326ce1bfa564ec74"},
1630
  ]
1631
 
1632
  [package.dependencies]
@@ -2129,15 +2284,70 @@ files = [
2129
  {file = "opentelemetry_util_http-0.45b0.tar.gz", hash = "sha256:4ce08b6a7d52dd7c96b7705b5b4f06fdb6aa3eac1233b3b0bfef8a0cab9a92cd"},
2130
  ]
2131
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2132
  [[package]]
2133
  name = "packaging"
2134
- version = "24.0"
2135
  description = "Core utilities for Python packages"
2136
  optional = false
2137
  python-versions = ">=3.7"
2138
  files = [
2139
- {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"},
2140
- {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"},
2141
  ]
2142
 
2143
  [[package]]
@@ -2209,6 +2419,21 @@ sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-d
2209
  test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"]
2210
  xml = ["lxml (>=4.9.2)"]
2211
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2212
  [[package]]
2213
  name = "pillow"
2214
  version = "10.3.0"
@@ -2360,18 +2585,18 @@ files = [
2360
 
2361
  [[package]]
2362
  name = "pydantic"
2363
- version = "2.7.1"
2364
  description = "Data validation using Python type hints"
2365
  optional = false
2366
  python-versions = ">=3.8"
2367
  files = [
2368
- {file = "pydantic-2.7.1-py3-none-any.whl", hash = "sha256:e029badca45266732a9a79898a15ae2e8b14840b1eabbb25844be28f0b33f3d5"},
2369
- {file = "pydantic-2.7.1.tar.gz", hash = "sha256:e9dbb5eada8abe4d9ae5f46b9939aead650cd2b68f249bb3a8139dbe125803cc"},
2370
  ]
2371
 
2372
  [package.dependencies]
2373
  annotated-types = ">=0.4.0"
2374
- pydantic-core = "2.18.2"
2375
  typing-extensions = ">=4.6.1"
2376
 
2377
  [package.extras]
@@ -2379,90 +2604,90 @@ email = ["email-validator (>=2.0.0)"]
2379
 
2380
  [[package]]
2381
  name = "pydantic-core"
2382
- version = "2.18.2"
2383
  description = "Core functionality for Pydantic validation and serialization"
2384
  optional = false
2385
  python-versions = ">=3.8"
2386
  files = [
2387
- {file = "pydantic_core-2.18.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9e08e867b306f525802df7cd16c44ff5ebbe747ff0ca6cf3fde7f36c05a59a81"},
2388
- {file = "pydantic_core-2.18.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f0a21cbaa69900cbe1a2e7cad2aa74ac3cf21b10c3efb0fa0b80305274c0e8a2"},
2389
- {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0680b1f1f11fda801397de52c36ce38ef1c1dc841a0927a94f226dea29c3ae3d"},
2390
- {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:95b9d5e72481d3780ba3442eac863eae92ae43a5f3adb5b4d0a1de89d42bb250"},
2391
- {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fcf5cd9c4b655ad666ca332b9a081112cd7a58a8b5a6ca7a3104bc950f2038"},
2392
- {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b5155ff768083cb1d62f3e143b49a8a3432e6789a3abee8acd005c3c7af1c74"},
2393
- {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:553ef617b6836fc7e4df130bb851e32fe357ce36336d897fd6646d6058d980af"},
2394
- {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b89ed9eb7d616ef5714e5590e6cf7f23b02d0d539767d33561e3675d6f9e3857"},
2395
- {file = "pydantic_core-2.18.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:75f7e9488238e920ab6204399ded280dc4c307d034f3924cd7f90a38b1829563"},
2396
- {file = "pydantic_core-2.18.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ef26c9e94a8c04a1b2924149a9cb081836913818e55681722d7f29af88fe7b38"},
2397
- {file = "pydantic_core-2.18.2-cp310-none-win32.whl", hash = "sha256:182245ff6b0039e82b6bb585ed55a64d7c81c560715d1bad0cbad6dfa07b4027"},
2398
- {file = "pydantic_core-2.18.2-cp310-none-win_amd64.whl", hash = "sha256:e23ec367a948b6d812301afc1b13f8094ab7b2c280af66ef450efc357d2ae543"},
2399
- {file = "pydantic_core-2.18.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:219da3f096d50a157f33645a1cf31c0ad1fe829a92181dd1311022f986e5fbe3"},
2400
- {file = "pydantic_core-2.18.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cc1cfd88a64e012b74e94cd00bbe0f9c6df57049c97f02bb07d39e9c852e19a4"},
2401
- {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b7133a6e6aeb8df37d6f413f7705a37ab4031597f64ab56384c94d98fa0e90"},
2402
- {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:224c421235f6102e8737032483f43c1a8cfb1d2f45740c44166219599358c2cd"},
2403
- {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b14d82cdb934e99dda6d9d60dc84a24379820176cc4a0d123f88df319ae9c150"},
2404
- {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2728b01246a3bba6de144f9e3115b532ee44bd6cf39795194fb75491824a1413"},
2405
- {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:470b94480bb5ee929f5acba6995251ada5e059a5ef3e0dfc63cca287283ebfa6"},
2406
- {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:997abc4df705d1295a42f95b4eec4950a37ad8ae46d913caeee117b6b198811c"},
2407
- {file = "pydantic_core-2.18.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75250dbc5290e3f1a0f4618db35e51a165186f9034eff158f3d490b3fed9f8a0"},
2408
- {file = "pydantic_core-2.18.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4456f2dca97c425231d7315737d45239b2b51a50dc2b6f0c2bb181fce6207664"},
2409
- {file = "pydantic_core-2.18.2-cp311-none-win32.whl", hash = "sha256:269322dcc3d8bdb69f054681edff86276b2ff972447863cf34c8b860f5188e2e"},
2410
- {file = "pydantic_core-2.18.2-cp311-none-win_amd64.whl", hash = "sha256:800d60565aec896f25bc3cfa56d2277d52d5182af08162f7954f938c06dc4ee3"},
2411
- {file = "pydantic_core-2.18.2-cp311-none-win_arm64.whl", hash = "sha256:1404c69d6a676245199767ba4f633cce5f4ad4181f9d0ccb0577e1f66cf4c46d"},
2412
- {file = "pydantic_core-2.18.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:fb2bd7be70c0fe4dfd32c951bc813d9fe6ebcbfdd15a07527796c8204bd36242"},
2413
- {file = "pydantic_core-2.18.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6132dd3bd52838acddca05a72aafb6eab6536aa145e923bb50f45e78b7251043"},
2414
- {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d904828195733c183d20a54230c0df0eb46ec746ea1a666730787353e87182"},
2415
- {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c9bd70772c720142be1020eac55f8143a34ec9f82d75a8e7a07852023e46617f"},
2416
- {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b8ed04b3582771764538f7ee7001b02e1170223cf9b75dff0bc698fadb00cf3"},
2417
- {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e6dac87ddb34aaec85f873d737e9d06a3555a1cc1a8e0c44b7f8d5daeb89d86f"},
2418
- {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ca4ae5a27ad7a4ee5170aebce1574b375de390bc01284f87b18d43a3984df72"},
2419
- {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:886eec03591b7cf058467a70a87733b35f44707bd86cf64a615584fd72488b7c"},
2420
- {file = "pydantic_core-2.18.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ca7b0c1f1c983e064caa85f3792dd2fe3526b3505378874afa84baf662e12241"},
2421
- {file = "pydantic_core-2.18.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b4356d3538c3649337df4074e81b85f0616b79731fe22dd11b99499b2ebbdf3"},
2422
- {file = "pydantic_core-2.18.2-cp312-none-win32.whl", hash = "sha256:8b172601454f2d7701121bbec3425dd71efcb787a027edf49724c9cefc14c038"},
2423
- {file = "pydantic_core-2.18.2-cp312-none-win_amd64.whl", hash = "sha256:b1bd7e47b1558ea872bd16c8502c414f9e90dcf12f1395129d7bb42a09a95438"},
2424
- {file = "pydantic_core-2.18.2-cp312-none-win_arm64.whl", hash = "sha256:98758d627ff397e752bc339272c14c98199c613f922d4a384ddc07526c86a2ec"},
2425
- {file = "pydantic_core-2.18.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:9fdad8e35f278b2c3eb77cbdc5c0a49dada440657bf738d6905ce106dc1de439"},
2426
- {file = "pydantic_core-2.18.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1d90c3265ae107f91a4f279f4d6f6f1d4907ac76c6868b27dc7fb33688cfb347"},
2427
- {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:390193c770399861d8df9670fb0d1874f330c79caaca4642332df7c682bf6b91"},
2428
- {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:82d5d4d78e4448683cb467897fe24e2b74bb7b973a541ea1dcfec1d3cbce39fb"},
2429
- {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4774f3184d2ef3e14e8693194f661dea5a4d6ca4e3dc8e39786d33a94865cefd"},
2430
- {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d4d938ec0adf5167cb335acb25a4ee69a8107e4984f8fbd2e897021d9e4ca21b"},
2431
- {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0e8b1be28239fc64a88a8189d1df7fad8be8c1ae47fcc33e43d4be15f99cc70"},
2432
- {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:868649da93e5a3d5eacc2b5b3b9235c98ccdbfd443832f31e075f54419e1b96b"},
2433
- {file = "pydantic_core-2.18.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:78363590ef93d5d226ba21a90a03ea89a20738ee5b7da83d771d283fd8a56761"},
2434
- {file = "pydantic_core-2.18.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:852e966fbd035a6468fc0a3496589b45e2208ec7ca95c26470a54daed82a0788"},
2435
- {file = "pydantic_core-2.18.2-cp38-none-win32.whl", hash = "sha256:6a46e22a707e7ad4484ac9ee9f290f9d501df45954184e23fc29408dfad61350"},
2436
- {file = "pydantic_core-2.18.2-cp38-none-win_amd64.whl", hash = "sha256:d91cb5ea8b11607cc757675051f61b3d93f15eca3cefb3e6c704a5d6e8440f4e"},
2437
- {file = "pydantic_core-2.18.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ae0a8a797a5e56c053610fa7be147993fe50960fa43609ff2a9552b0e07013e8"},
2438
- {file = "pydantic_core-2.18.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:042473b6280246b1dbf530559246f6842b56119c2926d1e52b631bdc46075f2a"},
2439
- {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a388a77e629b9ec814c1b1e6b3b595fe521d2cdc625fcca26fbc2d44c816804"},
2440
- {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e25add29b8f3b233ae90ccef2d902d0ae0432eb0d45370fe315d1a5cf231004b"},
2441
- {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f459a5ce8434614dfd39bbebf1041952ae01da6bed9855008cb33b875cb024c0"},
2442
- {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eff2de745698eb46eeb51193a9f41d67d834d50e424aef27df2fcdee1b153845"},
2443
- {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8309f67285bdfe65c372ea3722b7a5642680f3dba538566340a9d36e920b5f0"},
2444
- {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f93a8a2e3938ff656a7c1bc57193b1319960ac015b6e87d76c76bf14fe0244b4"},
2445
- {file = "pydantic_core-2.18.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:22057013c8c1e272eb8d0eebc796701167d8377441ec894a8fed1af64a0bf399"},
2446
- {file = "pydantic_core-2.18.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cfeecd1ac6cc1fb2692c3d5110781c965aabd4ec5d32799773ca7b1456ac636b"},
2447
- {file = "pydantic_core-2.18.2-cp39-none-win32.whl", hash = "sha256:0d69b4c2f6bb3e130dba60d34c0845ba31b69babdd3f78f7c0c8fae5021a253e"},
2448
- {file = "pydantic_core-2.18.2-cp39-none-win_amd64.whl", hash = "sha256:d9319e499827271b09b4e411905b24a426b8fb69464dfa1696258f53a3334641"},
2449
- {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a1874c6dd4113308bd0eb568418e6114b252afe44319ead2b4081e9b9521fe75"},
2450
- {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:ccdd111c03bfd3666bd2472b674c6899550e09e9f298954cfc896ab92b5b0e6d"},
2451
- {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e18609ceaa6eed63753037fc06ebb16041d17d28199ae5aba0052c51449650a9"},
2452
- {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e5c584d357c4e2baf0ff7baf44f4994be121e16a2c88918a5817331fc7599d7"},
2453
- {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43f0f463cf89ace478de71a318b1b4f05ebc456a9b9300d027b4b57c1a2064fb"},
2454
- {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:e1b395e58b10b73b07b7cf740d728dd4ff9365ac46c18751bf8b3d8cca8f625a"},
2455
- {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0098300eebb1c837271d3d1a2cd2911e7c11b396eac9661655ee524a7f10587b"},
2456
- {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:36789b70d613fbac0a25bb07ab3d9dba4d2e38af609c020cf4d888d165ee0bf3"},
2457
- {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3f9a801e7c8f1ef8718da265bba008fa121243dfe37c1cea17840b0944dfd72c"},
2458
- {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:3a6515ebc6e69d85502b4951d89131ca4e036078ea35533bb76327f8424531ce"},
2459
- {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20aca1e2298c56ececfd8ed159ae4dde2df0781988c97ef77d5c16ff4bd5b400"},
2460
- {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:223ee893d77a310a0391dca6df00f70bbc2f36a71a895cecd9a0e762dc37b349"},
2461
- {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2334ce8c673ee93a1d6a65bd90327588387ba073c17e61bf19b4fd97d688d63c"},
2462
- {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:cbca948f2d14b09d20268cda7b0367723d79063f26c4ffc523af9042cad95592"},
2463
- {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b3ef08e20ec49e02d5c6717a91bb5af9b20f1805583cb0adfe9ba2c6b505b5ae"},
2464
- {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c6fdc8627910eed0c01aed6a390a252fe3ea6d472ee70fdde56273f198938374"},
2465
- {file = "pydantic_core-2.18.2.tar.gz", hash = "sha256:2e29d20810dfc3043ee13ac7d9e25105799817683348823f305ab3f349b9386e"},
2466
  ]
2467
 
2468
  [package.dependencies]
@@ -2585,6 +2810,111 @@ files = [
2585
  {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
2586
  ]
2587
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2588
  [[package]]
2589
  name = "regex"
2590
  version = "2024.5.15"
@@ -3192,6 +3522,23 @@ files = [
3192
  {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"},
3193
  ]
3194
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3195
  [[package]]
3196
  name = "urllib3"
3197
  version = "2.2.1"
@@ -3646,4 +3993,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more
3646
  [metadata]
3647
  lock-version = "2.0"
3648
  python-versions = "^3.11,<3.12"
3649
- content-hash = "e1009d6d5a3112c225a6916b387f78d5e01bbda9edbd6ee1b78759540da5e72e"
 
380
  marshmallow = ">=3.18.0,<4.0.0"
381
  typing-inspect = ">=0.4.0,<1"
382
 
383
+ [[package]]
384
+ name = "dateparser"
385
+ version = "1.2.0"
386
+ description = "Date parsing library designed to parse dates from HTML pages"
387
+ optional = false
388
+ python-versions = ">=3.7"
389
+ files = [
390
+ {file = "dateparser-1.2.0-py2.py3-none-any.whl", hash = "sha256:0b21ad96534e562920a0083e97fd45fa959882d4162acc358705144520a35830"},
391
+ {file = "dateparser-1.2.0.tar.gz", hash = "sha256:7975b43a4222283e0ae15be7b4999d08c9a70e2d378ac87385b1ccf2cffbbb30"},
392
+ ]
393
+
394
+ [package.dependencies]
395
+ python-dateutil = "*"
396
+ pytz = "*"
397
+ regex = "<2019.02.19 || >2019.02.19,<2021.8.27 || >2021.8.27"
398
+ tzlocal = "*"
399
+
400
+ [package.extras]
401
+ calendars = ["convertdate", "hijri-converter"]
402
+ fasttext = ["fasttext"]
403
+ langdetect = ["langdetect"]
404
+
405
  [[package]]
406
  name = "deprecated"
407
  version = "1.2.14"
 
1023
  {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"},
1024
  ]
1025
 
1026
+ [[package]]
1027
+ name = "jsonpatch"
1028
+ version = "1.33"
1029
+ description = "Apply JSON-Patches (RFC 6902)"
1030
+ optional = false
1031
+ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*"
1032
+ files = [
1033
+ {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"},
1034
+ {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"},
1035
+ ]
1036
+
1037
+ [package.dependencies]
1038
+ jsonpointer = ">=1.9"
1039
+
1040
+ [[package]]
1041
+ name = "jsonpointer"
1042
+ version = "2.4"
1043
+ description = "Identify specific nodes in a JSON document (RFC 6901)"
1044
+ optional = false
1045
+ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*"
1046
+ files = [
1047
+ {file = "jsonpointer-2.4-py2.py3-none-any.whl", hash = "sha256:15d51bba20eea3165644553647711d150376234112651b4f1811022aecad7d7a"},
1048
+ {file = "jsonpointer-2.4.tar.gz", hash = "sha256:585cee82b70211fa9e6043b7bb89db6e1aa49524340dde8ad6b63206ea689d88"},
1049
+ ]
1050
+
1051
+ [[package]]
1052
+ name = "langchain"
1053
+ version = "0.2.1"
1054
+ description = "Building applications with LLMs through composability"
1055
+ optional = false
1056
+ python-versions = "<4.0,>=3.8.1"
1057
+ files = [
1058
+ {file = "langchain-0.2.1-py3-none-any.whl", hash = "sha256:3e13bf97c5717bce2c281f5117e8778823e8ccf62d949e73d3869448962b1c97"},
1059
+ {file = "langchain-0.2.1.tar.gz", hash = "sha256:5758a315e1ac92eb26dafec5ad0fafa03cafa686aba197d5bb0b1dd28cc03ebe"},
1060
+ ]
1061
+
1062
+ [package.dependencies]
1063
+ aiohttp = ">=3.8.3,<4.0.0"
1064
+ langchain-core = ">=0.2.0,<0.3.0"
1065
+ langchain-text-splitters = ">=0.2.0,<0.3.0"
1066
+ langsmith = ">=0.1.17,<0.2.0"
1067
+ numpy = ">=1,<2"
1068
+ pydantic = ">=1,<3"
1069
+ PyYAML = ">=5.3"
1070
+ requests = ">=2,<3"
1071
+ SQLAlchemy = ">=1.4,<3"
1072
+ tenacity = ">=8.1.0,<9.0.0"
1073
+
1074
+ [package.extras]
1075
+ azure = ["azure-ai-formrecognizer (>=3.2.1,<4.0.0)", "azure-ai-textanalytics (>=5.3.0,<6.0.0)", "azure-cognitiveservices-speech (>=1.28.0,<2.0.0)", "azure-core (>=1.26.4,<2.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "azure-search-documents (==11.4.0b8)", "openai (<2)"]
1076
+ clarifai = ["clarifai (>=9.1.0)"]
1077
+ cli = ["typer (>=0.9.0,<0.10.0)"]
1078
+ cohere = ["cohere (>=4,<6)"]
1079
+ docarray = ["docarray[hnswlib] (>=0.32.0,<0.33.0)"]
1080
+ embeddings = ["sentence-transformers (>=2,<3)"]
1081
+ extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.3.11,<0.4.0)", "arxiv (>=1.4,<2.0)", "assemblyai (>=0.17.0,<0.18.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "cassio (>=0.1.0,<0.2.0)", "chardet (>=5.1.0,<6.0.0)", "cohere (>=4,<6)", "couchbase (>=4.1.9,<5.0.0)", "dashvector (>=1.0.1,<2.0.0)", "databricks-vectorsearch (>=0.21,<0.22)", "datasets (>=2.15.0,<3.0.0)", "dgml-utils (>=0.3.0,<0.4.0)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "feedparser (>=6.0.10,<7.0.0)", "fireworks-ai (>=0.9.0,<0.10.0)", "geopandas (>=0.13.1,<0.14.0)", "gitpython (>=3.1.32,<4.0.0)", "google-cloud-documentai (>=2.20.1,<3.0.0)", "gql (>=3.4.1,<4.0.0)", "hologres-vector (>=0.0.6,<0.0.7)", "html2text (>=2020.1.16,<2021.0.0)", "javelin-sdk (>=0.1.8,<0.2.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "jsonschema (>1)", "langchain-openai (>=0.1,<0.2)", "lxml (>=4.9.3,<6.0)", "markdownify (>=0.11.6,<0.12.0)", "motor (>=3.3.1,<4.0.0)", "msal (>=1.25.0,<2.0.0)", "mwparserfromhell (>=0.6.4,<0.7.0)", "mwxml (>=0.3.3,<0.4.0)", "newspaper3k (>=0.2.8,<0.3.0)", "numexpr (>=2.8.6,<3.0.0)", "openai (<2)", "openapi-pydantic (>=0.3.2,<0.4.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pgvector (>=0.1.6,<0.2.0)", "praw (>=7.7.1,<8.0.0)", "psychicapi (>=0.8.0,<0.9.0)", "py-trello (>=0.19.0,<0.20.0)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "pyspark (>=3.4.0,<4.0.0)", "rank-bm25 (>=0.2.2,<0.3.0)", "rapidfuzz (>=3.1.1,<4.0.0)", "rapidocr-onnxruntime (>=1.3.2,<2.0.0)", "rdflib (==7.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "rspace_client (>=2.5.0,<3.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "sqlite-vss (>=0.1.2,<0.2.0)", "streamlit (>=1.18.0,<2.0.0)", "sympy (>=1.12,<2.0)", "telethon (>=1.28.5,<2.0.0)", "timescale-vector (>=0.0.1,<0.0.2)", "tqdm (>=4.48.0)", "upstash-redis (>=0.15.0,<0.16.0)", "xata (>=1.0.0a7,<2.0.0)", "xmltodict (>=0.13.0,<0.14.0)"]
1082
+ javascript = ["esprima (>=4.0.1,<5.0.0)"]
1083
+ llms = ["clarifai (>=9.1.0)", "cohere (>=4,<6)", "huggingface_hub (>=0,<1)", "manifest-ml (>=0.0.1,<0.0.2)", "nlpcloud (>=1,<2)", "openai (<2)", "openlm (>=0.0.5,<0.0.6)", "torch (>=1,<3)", "transformers (>=4,<5)"]
1084
+ openai = ["openai (<2)", "tiktoken (>=0.7,<1.0)"]
1085
+ qdrant = ["qdrant-client (>=1.3.1,<2.0.0)"]
1086
+ text-helpers = ["chardet (>=5.1.0,<6.0.0)"]
1087
+
1088
+ [[package]]
1089
+ name = "langchain-core"
1090
+ version = "0.2.3"
1091
+ description = "Building applications with LLMs through composability"
1092
+ optional = false
1093
+ python-versions = "<4.0,>=3.8.1"
1094
+ files = [
1095
+ {file = "langchain_core-0.2.3-py3-none-any.whl", hash = "sha256:22189b5a3a30bfd65eb995f95e627f7c2c3acb322feb89f5f5f2fb7df21833a7"},
1096
+ {file = "langchain_core-0.2.3.tar.gz", hash = "sha256:fbc75a64b9c0b7655d96ca57a707df1e6c09efc1539c36adbd73260612549810"},
1097
+ ]
1098
+
1099
+ [package.dependencies]
1100
+ jsonpatch = ">=1.33,<2.0"
1101
+ langsmith = ">=0.1.65,<0.2.0"
1102
+ packaging = ">=23.2,<24.0"
1103
+ pydantic = ">=1,<3"
1104
+ PyYAML = ">=5.3"
1105
+ tenacity = ">=8.1.0,<9.0.0"
1106
+
1107
+ [package.extras]
1108
+ extended-testing = ["jinja2 (>=3,<4)"]
1109
+
1110
+ [[package]]
1111
+ name = "langchain-openai"
1112
+ version = "0.1.8"
1113
+ description = "An integration package connecting OpenAI and LangChain"
1114
+ optional = false
1115
+ python-versions = "<4.0,>=3.8.1"
1116
+ files = [
1117
+ {file = "langchain_openai-0.1.8-py3-none-any.whl", hash = "sha256:8125c84223e9f43b05defbca64eedbcf362fd78a680de6c25e64f973b34a8063"},
1118
+ {file = "langchain_openai-0.1.8.tar.gz", hash = "sha256:a11fcce15def7917c44232abda6baaa63dfc79fe44be1531eea650d39a44cd95"},
1119
+ ]
1120
+
1121
+ [package.dependencies]
1122
+ langchain-core = ">=0.2.2,<0.3"
1123
+ openai = ">=1.26.0,<2.0.0"
1124
+ tiktoken = ">=0.7,<1"
1125
+
1126
+ [[package]]
1127
+ name = "langchain-text-splitters"
1128
+ version = "0.2.0"
1129
+ description = "LangChain text splitting utilities"
1130
+ optional = false
1131
+ python-versions = "<4.0,>=3.8.1"
1132
+ files = [
1133
+ {file = "langchain_text_splitters-0.2.0-py3-none-any.whl", hash = "sha256:7b4c6a45f8471630a882b321e138329b6897102a5bc62f4c12be1c0b05bb9199"},
1134
+ {file = "langchain_text_splitters-0.2.0.tar.gz", hash = "sha256:b32ab4f7397f7d42c1fa3283fefc2547ba356bd63a68ee9092865e5ad83c82f9"},
1135
+ ]
1136
+
1137
+ [package.dependencies]
1138
+ langchain-core = ">=0.2.0,<0.3.0"
1139
+
1140
+ [package.extras]
1141
+ extended-testing = ["beautifulsoup4 (>=4.12.3,<5.0.0)", "lxml (>=4.9.3,<6.0)"]
1142
+
1143
+ [[package]]
1144
+ name = "langsmith"
1145
+ version = "0.1.65"
1146
+ description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform."
1147
+ optional = false
1148
+ python-versions = "<4.0,>=3.8.1"
1149
+ files = [
1150
+ {file = "langsmith-0.1.65-py3-none-any.whl", hash = "sha256:ab4487029240e69cca30da1065f1e9138e5a7ca2bbe8c697f0bd7d5839f71cf7"},
1151
+ {file = "langsmith-0.1.65.tar.gz", hash = "sha256:d3c2eb2391478bd79989f02652cf66e29a7959d677614b6993a47cef43f7f43b"},
1152
+ ]
1153
+
1154
+ [package.dependencies]
1155
+ orjson = ">=3.9.14,<4.0.0"
1156
+ pydantic = ">=1,<3"
1157
+ requests = ">=2,<3"
1158
+
1159
  [[package]]
1160
  name = "llama-index"
1161
  version = "0.10.28"
 
1775
 
1776
  [[package]]
1777
  name = "openai"
1778
+ version = "1.30.5"
1779
  description = "The official Python library for the openai API"
1780
  optional = false
1781
  python-versions = ">=3.7.1"
1782
  files = [
1783
+ {file = "openai-1.30.5-py3-none-any.whl", hash = "sha256:2ad95e926de0d2e09cde632a9204b0a6dca4a03c2cdcc84329b01f355784355a"},
1784
+ {file = "openai-1.30.5.tar.gz", hash = "sha256:5366562eb2c5917e6116ae0391b7ae6e3acd62b0ae3f565ada32b35d8fcfa106"},
1785
  ]
1786
 
1787
  [package.dependencies]
 
2284
  {file = "opentelemetry_util_http-0.45b0.tar.gz", hash = "sha256:4ce08b6a7d52dd7c96b7705b5b4f06fdb6aa3eac1233b3b0bfef8a0cab9a92cd"},
2285
  ]
2286
 
2287
+ [[package]]
2288
+ name = "orjson"
2289
+ version = "3.10.3"
2290
+ description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy"
2291
+ optional = false
2292
+ python-versions = ">=3.8"
2293
+ files = [
2294
+ {file = "orjson-3.10.3-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9fb6c3f9f5490a3eb4ddd46fc1b6eadb0d6fc16fb3f07320149c3286a1409dd8"},
2295
+ {file = "orjson-3.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:252124b198662eee80428f1af8c63f7ff077c88723fe206a25df8dc57a57b1fa"},
2296
+ {file = "orjson-3.10.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9f3e87733823089a338ef9bbf363ef4de45e5c599a9bf50a7a9b82e86d0228da"},
2297
+ {file = "orjson-3.10.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c8334c0d87103bb9fbbe59b78129f1f40d1d1e8355bbed2ca71853af15fa4ed3"},
2298
+ {file = "orjson-3.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1952c03439e4dce23482ac846e7961f9d4ec62086eb98ae76d97bd41d72644d7"},
2299
+ {file = "orjson-3.10.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c0403ed9c706dcd2809f1600ed18f4aae50be263bd7112e54b50e2c2bc3ebd6d"},
2300
+ {file = "orjson-3.10.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:382e52aa4270a037d41f325e7d1dfa395b7de0c367800b6f337d8157367bf3a7"},
2301
+ {file = "orjson-3.10.3-cp310-none-win32.whl", hash = "sha256:be2aab54313752c04f2cbaab4515291ef5af8c2256ce22abc007f89f42f49109"},
2302
+ {file = "orjson-3.10.3-cp310-none-win_amd64.whl", hash = "sha256:416b195f78ae461601893f482287cee1e3059ec49b4f99479aedf22a20b1098b"},
2303
+ {file = "orjson-3.10.3-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:73100d9abbbe730331f2242c1fc0bcb46a3ea3b4ae3348847e5a141265479700"},
2304
+ {file = "orjson-3.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:544a12eee96e3ab828dbfcb4d5a0023aa971b27143a1d35dc214c176fdfb29b3"},
2305
+ {file = "orjson-3.10.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:520de5e2ef0b4ae546bea25129d6c7c74edb43fc6cf5213f511a927f2b28148b"},
2306
+ {file = "orjson-3.10.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ccaa0a401fc02e8828a5bedfd80f8cd389d24f65e5ca3954d72c6582495b4bcf"},
2307
+ {file = "orjson-3.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a7bc9e8bc11bac40f905640acd41cbeaa87209e7e1f57ade386da658092dc16"},
2308
+ {file = "orjson-3.10.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3582b34b70543a1ed6944aca75e219e1192661a63da4d039d088a09c67543b08"},
2309
+ {file = "orjson-3.10.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1c23dfa91481de880890d17aa7b91d586a4746a4c2aa9a145bebdbaf233768d5"},
2310
+ {file = "orjson-3.10.3-cp311-none-win32.whl", hash = "sha256:1770e2a0eae728b050705206d84eda8b074b65ee835e7f85c919f5705b006c9b"},
2311
+ {file = "orjson-3.10.3-cp311-none-win_amd64.whl", hash = "sha256:93433b3c1f852660eb5abdc1f4dd0ced2be031ba30900433223b28ee0140cde5"},
2312
+ {file = "orjson-3.10.3-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a39aa73e53bec8d410875683bfa3a8edf61e5a1c7bb4014f65f81d36467ea098"},
2313
+ {file = "orjson-3.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0943a96b3fa09bee1afdfccc2cb236c9c64715afa375b2af296c73d91c23eab2"},
2314
+ {file = "orjson-3.10.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e852baafceff8da3c9defae29414cc8513a1586ad93e45f27b89a639c68e8176"},
2315
+ {file = "orjson-3.10.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18566beb5acd76f3769c1d1a7ec06cdb81edc4d55d2765fb677e3eaa10fa99e0"},
2316
+ {file = "orjson-3.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bd2218d5a3aa43060efe649ec564ebedec8ce6ae0a43654b81376216d5ebd42"},
2317
+ {file = "orjson-3.10.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:cf20465e74c6e17a104ecf01bf8cd3b7b252565b4ccee4548f18b012ff2f8069"},
2318
+ {file = "orjson-3.10.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ba7f67aa7f983c4345eeda16054a4677289011a478ca947cd69c0a86ea45e534"},
2319
+ {file = "orjson-3.10.3-cp312-none-win32.whl", hash = "sha256:17e0713fc159abc261eea0f4feda611d32eabc35708b74bef6ad44f6c78d5ea0"},
2320
+ {file = "orjson-3.10.3-cp312-none-win_amd64.whl", hash = "sha256:4c895383b1ec42b017dd2c75ae8a5b862fc489006afde06f14afbdd0309b2af0"},
2321
+ {file = "orjson-3.10.3-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:be2719e5041e9fb76c8c2c06b9600fe8e8584e6980061ff88dcbc2691a16d20d"},
2322
+ {file = "orjson-3.10.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0175a5798bdc878956099f5c54b9837cb62cfbf5d0b86ba6d77e43861bcec2"},
2323
+ {file = "orjson-3.10.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:978be58a68ade24f1af7758626806e13cff7748a677faf95fbb298359aa1e20d"},
2324
+ {file = "orjson-3.10.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16bda83b5c61586f6f788333d3cf3ed19015e3b9019188c56983b5a299210eb5"},
2325
+ {file = "orjson-3.10.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ad1f26bea425041e0a1adad34630c4825a9e3adec49079b1fb6ac8d36f8b754"},
2326
+ {file = "orjson-3.10.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:9e253498bee561fe85d6325ba55ff2ff08fb5e7184cd6a4d7754133bd19c9195"},
2327
+ {file = "orjson-3.10.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0a62f9968bab8a676a164263e485f30a0b748255ee2f4ae49a0224be95f4532b"},
2328
+ {file = "orjson-3.10.3-cp38-none-win32.whl", hash = "sha256:8d0b84403d287d4bfa9bf7d1dc298d5c1c5d9f444f3737929a66f2fe4fb8f134"},
2329
+ {file = "orjson-3.10.3-cp38-none-win_amd64.whl", hash = "sha256:8bc7a4df90da5d535e18157220d7915780d07198b54f4de0110eca6b6c11e290"},
2330
+ {file = "orjson-3.10.3-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9059d15c30e675a58fdcd6f95465c1522b8426e092de9fff20edebfdc15e1cb0"},
2331
+ {file = "orjson-3.10.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d40c7f7938c9c2b934b297412c067936d0b54e4b8ab916fd1a9eb8f54c02294"},
2332
+ {file = "orjson-3.10.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d4a654ec1de8fdaae1d80d55cee65893cb06494e124681ab335218be6a0691e7"},
2333
+ {file = "orjson-3.10.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:831c6ef73f9aa53c5f40ae8f949ff7681b38eaddb6904aab89dca4d85099cb78"},
2334
+ {file = "orjson-3.10.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99b880d7e34542db89f48d14ddecbd26f06838b12427d5a25d71baceb5ba119d"},
2335
+ {file = "orjson-3.10.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2e5e176c994ce4bd434d7aafb9ecc893c15f347d3d2bbd8e7ce0b63071c52e25"},
2336
+ {file = "orjson-3.10.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b69a58a37dab856491bf2d3bbf259775fdce262b727f96aafbda359cb1d114d8"},
2337
+ {file = "orjson-3.10.3-cp39-none-win32.whl", hash = "sha256:b8d4d1a6868cde356f1402c8faeb50d62cee765a1f7ffcfd6de732ab0581e063"},
2338
+ {file = "orjson-3.10.3-cp39-none-win_amd64.whl", hash = "sha256:5102f50c5fc46d94f2033fe00d392588564378260d64377aec702f21a7a22912"},
2339
+ {file = "orjson-3.10.3.tar.gz", hash = "sha256:2b166507acae7ba2f7c315dcf185a9111ad5e992ac81f2d507aac39193c2c818"},
2340
+ ]
2341
+
2342
  [[package]]
2343
  name = "packaging"
2344
+ version = "23.2"
2345
  description = "Core utilities for Python packages"
2346
  optional = false
2347
  python-versions = ">=3.7"
2348
  files = [
2349
+ {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
2350
+ {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
2351
  ]
2352
 
2353
  [[package]]
 
2419
  test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"]
2420
  xml = ["lxml (>=4.9.2)"]
2421
 
2422
+ [[package]]
2423
+ name = "path"
2424
+ version = "16.14.0"
2425
+ description = "A module wrapper for os.path"
2426
+ optional = false
2427
+ python-versions = ">=3.8"
2428
+ files = [
2429
+ {file = "path-16.14.0-py3-none-any.whl", hash = "sha256:8ee37703cbdc7cc83835ed4ecc6b638226fb2b43b7b45f26b620589981a109a5"},
2430
+ {file = "path-16.14.0.tar.gz", hash = "sha256:dbaaa7efd4602fd6ba8d82890dc7823d69e5de740a6e842d9919b0faaf2b6a8e"},
2431
+ ]
2432
+
2433
+ [package.extras]
2434
+ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
2435
+ testing = ["appdirs", "more-itertools", "packaging", "pygments", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "pywin32"]
2436
+
2437
  [[package]]
2438
  name = "pillow"
2439
  version = "10.3.0"
 
2585
 
2586
  [[package]]
2587
  name = "pydantic"
2588
+ version = "2.7.2"
2589
  description = "Data validation using Python type hints"
2590
  optional = false
2591
  python-versions = ">=3.8"
2592
  files = [
2593
+ {file = "pydantic-2.7.2-py3-none-any.whl", hash = "sha256:834ab954175f94e6e68258537dc49402c4a5e9d0409b9f1b86b7e934a8372de7"},
2594
+ {file = "pydantic-2.7.2.tar.gz", hash = "sha256:71b2945998f9c9b7919a45bde9a50397b289937d215ae141c1d0903ba7149fd7"},
2595
  ]
2596
 
2597
  [package.dependencies]
2598
  annotated-types = ">=0.4.0"
2599
+ pydantic-core = "2.18.3"
2600
  typing-extensions = ">=4.6.1"
2601
 
2602
  [package.extras]
 
2604
 
2605
  [[package]]
2606
  name = "pydantic-core"
2607
+ version = "2.18.3"
2608
  description = "Core functionality for Pydantic validation and serialization"
2609
  optional = false
2610
  python-versions = ">=3.8"
2611
  files = [
2612
+ {file = "pydantic_core-2.18.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:744697428fcdec6be5670460b578161d1ffe34743a5c15656be7ea82b008197c"},
2613
+ {file = "pydantic_core-2.18.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37b40c05ced1ba4218b14986fe6f283d22e1ae2ff4c8e28881a70fb81fbfcda7"},
2614
+ {file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:544a9a75622357076efb6b311983ff190fbfb3c12fc3a853122b34d3d358126c"},
2615
+ {file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e2e253af04ceaebde8eb201eb3f3e3e7e390f2d275a88300d6a1959d710539e2"},
2616
+ {file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:855ec66589c68aa367d989da5c4755bb74ee92ccad4fdb6af942c3612c067e34"},
2617
+ {file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d3e42bb54e7e9d72c13ce112e02eb1b3b55681ee948d748842171201a03a98a"},
2618
+ {file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6ac9ffccc9d2e69d9fba841441d4259cb668ac180e51b30d3632cd7abca2b9b"},
2619
+ {file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c56eca1686539fa0c9bda992e7bd6a37583f20083c37590413381acfc5f192d6"},
2620
+ {file = "pydantic_core-2.18.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:17954d784bf8abfc0ec2a633108207ebc4fa2df1a0e4c0c3ccbaa9bb01d2c426"},
2621
+ {file = "pydantic_core-2.18.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:98ed737567d8f2ecd54f7c8d4f8572ca7c7921ede93a2e52939416170d357812"},
2622
+ {file = "pydantic_core-2.18.3-cp310-none-win32.whl", hash = "sha256:9f9e04afebd3ed8c15d67a564ed0a34b54e52136c6d40d14c5547b238390e779"},
2623
+ {file = "pydantic_core-2.18.3-cp310-none-win_amd64.whl", hash = "sha256:45e4ffbae34f7ae30d0047697e724e534a7ec0a82ef9994b7913a412c21462a0"},
2624
+ {file = "pydantic_core-2.18.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:b9ebe8231726c49518b16b237b9fe0d7d361dd221302af511a83d4ada01183ab"},
2625
+ {file = "pydantic_core-2.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b8e20e15d18bf7dbb453be78a2d858f946f5cdf06c5072453dace00ab652e2b2"},
2626
+ {file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0d9ff283cd3459fa0bf9b0256a2b6f01ac1ff9ffb034e24457b9035f75587cb"},
2627
+ {file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f7ef5f0ebb77ba24c9970da18b771711edc5feaf00c10b18461e0f5f5949231"},
2628
+ {file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73038d66614d2e5cde30435b5afdced2b473b4c77d4ca3a8624dd3e41a9c19be"},
2629
+ {file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6afd5c867a74c4d314c557b5ea9520183fadfbd1df4c2d6e09fd0d990ce412cd"},
2630
+ {file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd7df92f28d351bb9f12470f4c533cf03d1b52ec5a6e5c58c65b183055a60106"},
2631
+ {file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:80aea0ffeb1049336043d07799eace1c9602519fb3192916ff525b0287b2b1e4"},
2632
+ {file = "pydantic_core-2.18.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:aaee40f25bba38132e655ffa3d1998a6d576ba7cf81deff8bfa189fb43fd2bbe"},
2633
+ {file = "pydantic_core-2.18.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9128089da8f4fe73f7a91973895ebf2502539d627891a14034e45fb9e707e26d"},
2634
+ {file = "pydantic_core-2.18.3-cp311-none-win32.whl", hash = "sha256:fec02527e1e03257aa25b1a4dcbe697b40a22f1229f5d026503e8b7ff6d2eda7"},
2635
+ {file = "pydantic_core-2.18.3-cp311-none-win_amd64.whl", hash = "sha256:58ff8631dbab6c7c982e6425da8347108449321f61fe427c52ddfadd66642af7"},
2636
+ {file = "pydantic_core-2.18.3-cp311-none-win_arm64.whl", hash = "sha256:3fc1c7f67f34c6c2ef9c213e0f2a351797cda98249d9ca56a70ce4ebcaba45f4"},
2637
+ {file = "pydantic_core-2.18.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f0928cde2ae416a2d1ebe6dee324709c6f73e93494d8c7aea92df99aab1fc40f"},
2638
+ {file = "pydantic_core-2.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bee9bb305a562f8b9271855afb6ce00223f545de3d68560b3c1649c7c5295e9"},
2639
+ {file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e862823be114387257dacbfa7d78547165a85d7add33b446ca4f4fae92c7ff5c"},
2640
+ {file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6a36f78674cbddc165abab0df961b5f96b14461d05feec5e1f78da58808b97e7"},
2641
+ {file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba905d184f62e7ddbb7a5a751d8a5c805463511c7b08d1aca4a3e8c11f2e5048"},
2642
+ {file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7fdd362f6a586e681ff86550b2379e532fee63c52def1c666887956748eaa326"},
2643
+ {file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24b214b7ee3bd3b865e963dbed0f8bc5375f49449d70e8d407b567af3222aae4"},
2644
+ {file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:691018785779766127f531674fa82bb368df5b36b461622b12e176c18e119022"},
2645
+ {file = "pydantic_core-2.18.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:60e4c625e6f7155d7d0dcac151edf5858102bc61bf959d04469ca6ee4e8381bd"},
2646
+ {file = "pydantic_core-2.18.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4e651e47d981c1b701dcc74ab8fec5a60a5b004650416b4abbef13db23bc7be"},
2647
+ {file = "pydantic_core-2.18.3-cp312-none-win32.whl", hash = "sha256:ffecbb5edb7f5ffae13599aec33b735e9e4c7676ca1633c60f2c606beb17efc5"},
2648
+ {file = "pydantic_core-2.18.3-cp312-none-win_amd64.whl", hash = "sha256:2c8333f6e934733483c7eddffdb094c143b9463d2af7e6bd85ebcb2d4a1b82c6"},
2649
+ {file = "pydantic_core-2.18.3-cp312-none-win_arm64.whl", hash = "sha256:7a20dded653e516a4655f4c98e97ccafb13753987434fe7cf044aa25f5b7d417"},
2650
+ {file = "pydantic_core-2.18.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:eecf63195be644b0396f972c82598cd15693550f0ff236dcf7ab92e2eb6d3522"},
2651
+ {file = "pydantic_core-2.18.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2c44efdd3b6125419c28821590d7ec891c9cb0dff33a7a78d9d5c8b6f66b9702"},
2652
+ {file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e59fca51ffbdd1638b3856779342ed69bcecb8484c1d4b8bdb237d0eb5a45e2"},
2653
+ {file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:70cf099197d6b98953468461d753563b28e73cf1eade2ffe069675d2657ed1d5"},
2654
+ {file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:63081a49dddc6124754b32a3774331467bfc3d2bd5ff8f10df36a95602560361"},
2655
+ {file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:370059b7883485c9edb9655355ff46d912f4b03b009d929220d9294c7fd9fd60"},
2656
+ {file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a64faeedfd8254f05f5cf6fc755023a7e1606af3959cfc1a9285744cc711044"},
2657
+ {file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19d2e725de0f90d8671f89e420d36c3dd97639b98145e42fcc0e1f6d492a46dc"},
2658
+ {file = "pydantic_core-2.18.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:67bc078025d70ec5aefe6200ef094576c9d86bd36982df1301c758a9fff7d7f4"},
2659
+ {file = "pydantic_core-2.18.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:adf952c3f4100e203cbaf8e0c907c835d3e28f9041474e52b651761dc248a3c0"},
2660
+ {file = "pydantic_core-2.18.3-cp38-none-win32.whl", hash = "sha256:9a46795b1f3beb167eaee91736d5d17ac3a994bf2215a996aed825a45f897558"},
2661
+ {file = "pydantic_core-2.18.3-cp38-none-win_amd64.whl", hash = "sha256:200ad4e3133cb99ed82342a101a5abf3d924722e71cd581cc113fe828f727fbc"},
2662
+ {file = "pydantic_core-2.18.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:304378b7bf92206036c8ddd83a2ba7b7d1a5b425acafff637172a3aa72ad7083"},
2663
+ {file = "pydantic_core-2.18.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c826870b277143e701c9ccf34ebc33ddb4d072612683a044e7cce2d52f6c3fef"},
2664
+ {file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e201935d282707394f3668380e41ccf25b5794d1b131cdd96b07f615a33ca4b1"},
2665
+ {file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5560dda746c44b48bf82b3d191d74fe8efc5686a9ef18e69bdabccbbb9ad9442"},
2666
+ {file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b32c2a1f8032570842257e4c19288eba9a2bba4712af542327de9a1204faff8"},
2667
+ {file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:929c24e9dea3990bc8bcd27c5f2d3916c0c86f5511d2caa69e0d5290115344a9"},
2668
+ {file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1a8376fef60790152564b0eab376b3e23dd6e54f29d84aad46f7b264ecca943"},
2669
+ {file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dccf3ef1400390ddd1fb55bf0632209d39140552d068ee5ac45553b556780e06"},
2670
+ {file = "pydantic_core-2.18.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:41dbdcb0c7252b58fa931fec47937edb422c9cb22528f41cb8963665c372caf6"},
2671
+ {file = "pydantic_core-2.18.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:666e45cf071669fde468886654742fa10b0e74cd0fa0430a46ba6056b24fb0af"},
2672
+ {file = "pydantic_core-2.18.3-cp39-none-win32.whl", hash = "sha256:f9c08cabff68704a1b4667d33f534d544b8a07b8e5d039c37067fceb18789e78"},
2673
+ {file = "pydantic_core-2.18.3-cp39-none-win_amd64.whl", hash = "sha256:4afa5f5973e8572b5c0dcb4e2d4fda7890e7cd63329bd5cc3263a25c92ef0026"},
2674
+ {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:77319771a026f7c7d29c6ebc623de889e9563b7087911b46fd06c044a12aa5e9"},
2675
+ {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:df11fa992e9f576473038510d66dd305bcd51d7dd508c163a8c8fe148454e059"},
2676
+ {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d531076bdfb65af593326ffd567e6ab3da145020dafb9187a1d131064a55f97c"},
2677
+ {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d33ce258e4e6e6038f2b9e8b8a631d17d017567db43483314993b3ca345dcbbb"},
2678
+ {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1f9cd7f5635b719939019be9bda47ecb56e165e51dd26c9a217a433e3d0d59a9"},
2679
+ {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:cd4a032bb65cc132cae1fe3e52877daecc2097965cd3914e44fbd12b00dae7c5"},
2680
+ {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f2718430098bcdf60402136c845e4126a189959d103900ebabb6774a5d9fdb"},
2681
+ {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c0037a92cf0c580ed14e10953cdd26528e8796307bb8bb312dc65f71547df04d"},
2682
+ {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b95a0972fac2b1ff3c94629fc9081b16371dad870959f1408cc33b2f78ad347a"},
2683
+ {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a62e437d687cc148381bdd5f51e3e81f5b20a735c55f690c5be94e05da2b0d5c"},
2684
+ {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b367a73a414bbb08507da102dc2cde0fa7afe57d09b3240ce82a16d608a7679c"},
2685
+ {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ecce4b2360aa3f008da3327d652e74a0e743908eac306198b47e1c58b03dd2b"},
2686
+ {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bd4435b8d83f0c9561a2a9585b1de78f1abb17cb0cef5f39bf6a4b47d19bafe3"},
2687
+ {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:616221a6d473c5b9aa83fa8982745441f6a4a62a66436be9445c65f241b86c94"},
2688
+ {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:7e6382ce89a92bc1d0c0c5edd51e931432202b9080dc921d8d003e616402efd1"},
2689
+ {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ff58f379345603d940e461eae474b6bbb6dab66ed9a851ecd3cb3709bf4dcf6a"},
2690
+ {file = "pydantic_core-2.18.3.tar.gz", hash = "sha256:432e999088d85c8f36b9a3f769a8e2b57aabd817bbb729a90d1fe7f18f6f1f39"},
2691
  ]
2692
 
2693
  [package.dependencies]
 
2810
  {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
2811
  ]
2812
 
2813
+ [[package]]
2814
+ name = "rapidfuzz"
2815
+ version = "3.9.2"
2816
+ description = "rapid fuzzy string matching"
2817
+ optional = false
2818
+ python-versions = ">=3.8"
2819
+ files = [
2820
+ {file = "rapidfuzz-3.9.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:45e0c3e279e70589381f47ad410de7211bac943e827eb09eb8339d2124abca90"},
2821
+ {file = "rapidfuzz-3.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:280ef2f3066df9c486ffd3874d2489978fb8021044c47c006eb96be8d47917d7"},
2822
+ {file = "rapidfuzz-3.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe128ac0e05ca3a71d8ff18e70884a64fde00b6fbd2b4d9f59f7a4d798257c55"},
2823
+ {file = "rapidfuzz-3.9.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8fbc0f6e1b6f4063b937d0edcf0a56cbc1d7179ade9b7d6c849c94e44a7b20f6"},
2824
+ {file = "rapidfuzz-3.9.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:df19455c2fb85e86a721111b84ac8dd3685194f0edc9faefb226731ad3e134a7"},
2825
+ {file = "rapidfuzz-3.9.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:801a5d97c465a3467b3cdf50cdcdadec129ddca582b24430f5d24c715c80be9b"},
2826
+ {file = "rapidfuzz-3.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81f218524596d261a6cb33cda965687e62dd30def478d39f0befa243642c3985"},
2827
+ {file = "rapidfuzz-3.9.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5c61d53f293b4e3286919b0e081513367afabcb5aef0b6f899d006117778e558"},
2828
+ {file = "rapidfuzz-3.9.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0ed70fc6627ae37319f822e5d8d21d561044e0b3331b6f0e6904476faa8d8ed7"},
2829
+ {file = "rapidfuzz-3.9.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:96fa229d06ee005d2f46374fb2af65590a590a6fa2fd56e66474829f5fa9adfe"},
2830
+ {file = "rapidfuzz-3.9.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6609e881b57cabb40d515cc226bbf570e32e768bd2cc688ba026a45ffbc60875"},
2831
+ {file = "rapidfuzz-3.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:204fd4d293ef4d409c4142ddf830b7613924b998670f67e512ab1f880a60218a"},
2832
+ {file = "rapidfuzz-3.9.2-cp310-cp310-win32.whl", hash = "sha256:5b331a09446bc8f8971cf488c9e6c0f7dbf2739828588e063cf08fd400638a24"},
2833
+ {file = "rapidfuzz-3.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:01a9975984953fe549649e6a4c3f0d9c60707acf458184ec09678d6a57560112"},
2834
+ {file = "rapidfuzz-3.9.2-cp310-cp310-win_arm64.whl", hash = "sha256:ca4af5d7fc9c17bdc498aa1cab9ecf5140c8535c9cedeba1990bbe4b8be75098"},
2835
+ {file = "rapidfuzz-3.9.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:300ab53981a5d6831fe7e0f30c407c79520ad0f0ab51b2cece8717689026f495"},
2836
+ {file = "rapidfuzz-3.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f4828642acdb075154ce2ff3260f8afb6a17b5b0c8a437efbadac06e9995dd7b"},
2837
+ {file = "rapidfuzz-3.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b262883c3ce93dee1a9a974992961c8098e96b8142e2e01cabdb15ea8105c4a"},
2838
+ {file = "rapidfuzz-3.9.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf8582d85e35641734d6c1f43eb37c1f2a5eda338d3cfa8e651e078246b9ec58"},
2839
+ {file = "rapidfuzz-3.9.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e33b61ef87e1876d216c479fa2256233b3bb0424465ab2db1d94ab7b8649ae1c"},
2840
+ {file = "rapidfuzz-3.9.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fa1b3eb21756003a6a3977847dd4e0e9a26e2e02731d9daa5e92a9258e7f0db"},
2841
+ {file = "rapidfuzz-3.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:923ae0301a56356364f1159e3005fbeb2191e7a0e8705d5cc1b481d9eea27b97"},
2842
+ {file = "rapidfuzz-3.9.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8e4041cfd87f0a022aa8a9a187d3b0824e35be2bd9b3bceada11578ddd9ad65"},
2843
+ {file = "rapidfuzz-3.9.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1f832b430f976727bdbba009ee64acda25412602976fbfb2113d41e765d81849"},
2844
+ {file = "rapidfuzz-3.9.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6ce5e57e0c6acf5a98ffbdfaf8bccb6e41fbddb9eda3e041f4cc69b7cade5fa0"},
2845
+ {file = "rapidfuzz-3.9.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d65f34e71102d9cbe733d4ba1c645e7623eef850562501bab1ac79d217831436"},
2846
+ {file = "rapidfuzz-3.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5dd9ba4df0db46b9f909289e4687cc7721c622985c4cd169969005dd30fc1e24"},
2847
+ {file = "rapidfuzz-3.9.2-cp311-cp311-win32.whl", hash = "sha256:34c8bca3fef33d7e71f290de68be2184fac7a9e136fa0ed22b17ec597e181406"},
2848
+ {file = "rapidfuzz-3.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:91e1a8872c0b8aef95c33db86d25e8bdea6f557b9cdf683123c25035b2bcfb8e"},
2849
+ {file = "rapidfuzz-3.9.2-cp311-cp311-win_arm64.whl", hash = "sha256:ed02d73e46b7a4604d2bc1e0364b25f204862d40dd162f6b36ee22b9bf6d9df2"},
2850
+ {file = "rapidfuzz-3.9.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ae6c4ba2778b097397968130f2b0cb795cdc415c115539a49ce798f606152ad5"},
2851
+ {file = "rapidfuzz-3.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7270556ddebaa98fb777f493f17ed6a733b3527de16c43342bce1db109042845"},
2852
+ {file = "rapidfuzz-3.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4625273447bdd94f2ab06b2951cd8b74356c3a48552208279a3ec2947ceee141"},
2853
+ {file = "rapidfuzz-3.9.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5107b5ec8821453f7cac70b2d0bc4866699b25bff4819ada8b28bf2b11e87f65"},
2854
+ {file = "rapidfuzz-3.9.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b04c851d309df8261ed42951444db657936234ceddf4032f4409b0214c95ecbe"},
2855
+ {file = "rapidfuzz-3.9.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aeefff80f3f5d6841c30ffe0cdc84d62874de5a64cff509ae26fbd7478297af8"},
2856
+ {file = "rapidfuzz-3.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cdc106b5a99edd46443449c767287dbb5d4464a7536475a365e368e7ee4d651"},
2857
+ {file = "rapidfuzz-3.9.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ce253a2b7a71a01a4abac71ac31fd05f6ac1f1cd2af2d98fa80fe5c402175e54"},
2858
+ {file = "rapidfuzz-3.9.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5c30407cadbfe99753b7a996f0dd6da490b1e27d318c01db227e8f49770a01ec"},
2859
+ {file = "rapidfuzz-3.9.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:fb3fc387783f70387a91aababd8a5faeb230931b655ad99bcf838cd72404ba66"},
2860
+ {file = "rapidfuzz-3.9.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:c409852a89535ec8720301a847bab198c1c14d0f34ed07dfabbb90b1dbfc506d"},
2861
+ {file = "rapidfuzz-3.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8603050e547249c1cc8a8dc6a49917076572ea69b04bc51eb1748c403cfc9f46"},
2862
+ {file = "rapidfuzz-3.9.2-cp312-cp312-win32.whl", hash = "sha256:77bdb96e82d8831f0dd6db83e2ff0d4a731cff53e926d029c65a1dc3ae0f160a"},
2863
+ {file = "rapidfuzz-3.9.2-cp312-cp312-win_amd64.whl", hash = "sha256:09f354fa28e0fd170c6e4eea5e97eea0dba43761067df93109f49a5414ca8584"},
2864
+ {file = "rapidfuzz-3.9.2-cp312-cp312-win_arm64.whl", hash = "sha256:168299c9a2b4f20f10c1bb96d8da0bb05bf1f3b9957be3a0bae5db65ce9f095f"},
2865
+ {file = "rapidfuzz-3.9.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d87621d60078f87cb52082b1cbf9849afeaa1cb6d0a2b072fce25fe21c8675b4"},
2866
+ {file = "rapidfuzz-3.9.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c447d0e534418ef3eaabcd890d85c7e9f289c1c6ef6e060a0b1f239799781747"},
2867
+ {file = "rapidfuzz-3.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7161b205f25eff5f88ab809fb05a2a102634e06f452c0deb9535c9f41cd7b0a"},
2868
+ {file = "rapidfuzz-3.9.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f13a6bbadba8fdd42676c1213ebc692bba9fac00f7db0ae92acc06bb734294c4"},
2869
+ {file = "rapidfuzz-3.9.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:54534743820a15bd0dc30a0a0010825be337973236550fd63587700a7950bbca"},
2870
+ {file = "rapidfuzz-3.9.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bea61851a4c2f93148aa2779458fb3f70a62342d77c9ec3d9d08445c8485b738"},
2871
+ {file = "rapidfuzz-3.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e941f81a60351a842976fea208e6a6701a5899eb8a80b907e57d7c3099337900"},
2872
+ {file = "rapidfuzz-3.9.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:1bbfaf439e48efe3a48cada946cf7678b09c818ce9668e09dac40d05b772f6f8"},
2873
+ {file = "rapidfuzz-3.9.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:574f464da18d660712e9776072572d462cf6a26144c833d18d9c93778286e023"},
2874
+ {file = "rapidfuzz-3.9.2-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:8a56c494246d29aacf5ac93ca3cf338d79588a1a5c05d8f496c3f4d7127e9031"},
2875
+ {file = "rapidfuzz-3.9.2-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:2943b0f17195c000948a7668bb11979ea0e50079a3d3db9d139e51b68c3a7c26"},
2876
+ {file = "rapidfuzz-3.9.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:27214f93555d4f9b7b1baf107a6ba13e9daee21f1ec6e36418556d04a7ee4d9b"},
2877
+ {file = "rapidfuzz-3.9.2-cp38-cp38-win32.whl", hash = "sha256:876c6628fec6241262c27f8fda3c73bab88e205e9b9394c8868361e2eda59048"},
2878
+ {file = "rapidfuzz-3.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:cf1952b486589ffcfbde2015ca9be15e0f4b0e63d1e2c25f3daec0263fda4e69"},
2879
+ {file = "rapidfuzz-3.9.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1ca9a135060ee4d887d6af86493c3e0eb1c99ca205bca943fe5994dc93e648d5"},
2880
+ {file = "rapidfuzz-3.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:723518c9a18e8bda996d77aa9307b6f8b0e77905702b2772b020adf24191073a"},
2881
+ {file = "rapidfuzz-3.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65eb9aeae73ac60e53a9d6c509daaa217ea256a5e184eb8920c9b15295c48677"},
2882
+ {file = "rapidfuzz-3.9.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef2964f4eb9a37487c96e5e32167a3c4fa51bf8e899853d0ac67e0465a27702c"},
2883
+ {file = "rapidfuzz-3.9.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c64a252c96f29667c206726903bb9705c5195f01850360c9b9268de92ac878dc"},
2884
+ {file = "rapidfuzz-3.9.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b32b03398517b5e33c7f36d625a00fcb1c955b9fe3c939325688175fb21730"},
2885
+ {file = "rapidfuzz-3.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec5f7b1bac77439b624f5acbd8bfe61e7b833678701068b43f7a489c151427c0"},
2886
+ {file = "rapidfuzz-3.9.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5fd1b49fba8b4b9172eed5b131c1e9864d4d76bebea34359274f16a3591e5f44"},
2887
+ {file = "rapidfuzz-3.9.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c05b033fc3ff043f48e744f67038af7fd34003047c7810f24bec7c01ce7da05b"},
2888
+ {file = "rapidfuzz-3.9.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c3bea20db89b510d78d017b349b9d87159c32418693ddf091d9035dbe20b4dc0"},
2889
+ {file = "rapidfuzz-3.9.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:77226a77590f83ee073f4f8cc86a1232da88e24d19d349361faa169fb17ba1cd"},
2890
+ {file = "rapidfuzz-3.9.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:83ed8bc2c942dc61ab739bbca1ead791143b4639dc92156d3060bd0b6f4541ea"},
2891
+ {file = "rapidfuzz-3.9.2-cp39-cp39-win32.whl", hash = "sha256:2db70f64974c10b76ae37d5cff6124dce791def815d4fdf5ac16fe60be88d905"},
2892
+ {file = "rapidfuzz-3.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:bdead23114206dea4a22ed3aad6565b99a9e4b3fff9837c423afc556d2814b1a"},
2893
+ {file = "rapidfuzz-3.9.2-cp39-cp39-win_arm64.whl", hash = "sha256:0ec69ad076cfc7c88323d671613e40bb8754ba95a203556d9a7759e60f0544e8"},
2894
+ {file = "rapidfuzz-3.9.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:018360654881e75131b227aa96cdaba543c438da881c70a12ca0c86e2c4083b2"},
2895
+ {file = "rapidfuzz-3.9.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:eaa8178ec9238f32f15b6e49f70b852accda0a848448c4e30bce77c6624ebaba"},
2896
+ {file = "rapidfuzz-3.9.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32dd79b0f90ce609df96d0d48ef4327cf1f0415b9274588a466d3610a775d2f9"},
2897
+ {file = "rapidfuzz-3.9.2-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:04a1c38a72a50f3e6d346a33d53fa51ba390552b3592fca64a07e54d749b439b"},
2898
+ {file = "rapidfuzz-3.9.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77ca96eec40e815f0cf10b00008f295fd26ca43792a844cf62588a8ea614e160"},
2899
+ {file = "rapidfuzz-3.9.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c01c515a928f295f49d588b6523f44b474f047f9f2de0079bc57bcd00b870778"},
2900
+ {file = "rapidfuzz-3.9.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:07e14ef260b6f4ee03dff07a0ac95a16aff1ddbc7e6171e07e49d2d61526f3be"},
2901
+ {file = "rapidfuzz-3.9.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:64f3480bddc12b89969930f12a50a1aeb53e09aad41cf8b27694d83ca1cc7864"},
2902
+ {file = "rapidfuzz-3.9.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3c9e33ec21755bda1878095537cb84848e9cf6510d4837d22144ba04e33df29"},
2903
+ {file = "rapidfuzz-3.9.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a70045e84225697ddf67d656aa25b70d6802e2ff339d51f9545fca5b9b13fb8c"},
2904
+ {file = "rapidfuzz-3.9.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9ec1fd328518c33adb9171afe8735137cb7b492e4a81cddc23568f9980c235c"},
2905
+ {file = "rapidfuzz-3.9.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:1fd8458fdac232766d55593c1228c70968f382fdc376c25685273f99b5d1d921"},
2906
+ {file = "rapidfuzz-3.9.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a373748fddb5403b562b6d682082de360bb08395f44e3cb7e74819461e39a16c"},
2907
+ {file = "rapidfuzz-3.9.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:45f80856db3e22cb5f96ad1572aa1d004714514625ed4668144661d8a7c7e61f"},
2908
+ {file = "rapidfuzz-3.9.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:663e52cf878e0ccbbad0744eb3e2bb83a784645b146f15611bac225bc218f19b"},
2909
+ {file = "rapidfuzz-3.9.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fbe4d3034a8cfe59a2b477375ad7d739b3e5935f10af08abdf64aae55780cad"},
2910
+ {file = "rapidfuzz-3.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd38abfda97e42b30093f207108dcba944beab1edf6624ba757cf57354063177"},
2911
+ {file = "rapidfuzz-3.9.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:16b41fe360387283a3184ce72d4d26d1928e7ce809268a88e8491a776dd770af"},
2912
+ {file = "rapidfuzz-3.9.2.tar.gz", hash = "sha256:c899d78709f8d4bd0059784fa27a9f6c53d04fc4aeaa21de7c0c8e34a7154e88"},
2913
+ ]
2914
+
2915
+ [package.extras]
2916
+ full = ["numpy"]
2917
+
2918
  [[package]]
2919
  name = "regex"
2920
  version = "2024.5.15"
 
3522
  {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"},
3523
  ]
3524
 
3525
+ [[package]]
3526
+ name = "tzlocal"
3527
+ version = "5.2"
3528
+ description = "tzinfo object for the local timezone"
3529
+ optional = false
3530
+ python-versions = ">=3.8"
3531
+ files = [
3532
+ {file = "tzlocal-5.2-py3-none-any.whl", hash = "sha256:49816ef2fe65ea8ac19d19aa7a1ae0551c834303d5014c6d5a62e4cbda8047b8"},
3533
+ {file = "tzlocal-5.2.tar.gz", hash = "sha256:8d399205578f1a9342816409cc1e46a93ebd5755e39ea2d85334bea911bf0e6e"},
3534
+ ]
3535
+
3536
+ [package.dependencies]
3537
+ tzdata = {version = "*", markers = "platform_system == \"Windows\""}
3538
+
3539
+ [package.extras]
3540
+ devenv = ["check-manifest", "pytest (>=4.3)", "pytest-cov", "pytest-mock (>=3.3)", "zest.releaser"]
3541
+
3542
  [[package]]
3543
  name = "urllib3"
3544
  version = "2.2.1"
 
3993
  [metadata]
3994
  lock-version = "2.0"
3995
  python-versions = "^3.11,<3.12"
3996
+ content-hash = "764a6a2edfd938e4128d185bb383ddc23dadaa25b9f5cf7215998a90b3cc760e"
pyproject.toml CHANGED
@@ -19,6 +19,15 @@ llama-index = "0.10.28"
19
  llama-index-core = "0.10.28"
20
  llama-index-vector-stores-pinecone = "^0.1.7"
21
  traceloop-sdk = "^0.19.0"
 
 
 
 
 
 
 
 
 
22
 
23
  [tool.poetry.dependencies.uvicorn]
24
  extras = [ "standard" ]
 
19
  llama-index-core = "0.10.28"
20
  llama-index-vector-stores-pinecone = "^0.1.7"
21
  traceloop-sdk = "^0.19.0"
22
+ langchain = "^0.2.1"
23
+ langchain-openai = "^0.1.8"
24
+ openai = "^1.30.5"
25
+ tenacity = "^8.3.0"
26
+ rapidfuzz = "^3.9.2"
27
+ pydantic = "^2.7.2"
28
+ dateparser = "^1.2.0"
29
+ pandas = "^2.2.2"
30
+ path = "^16.14.0"
31
 
32
  [tool.poetry.dependencies.uvicorn]
33
  extras = [ "standard" ]
requirements.txt DELETED
@@ -1,11 +0,0 @@
1
- aiostream==0.5.2
2
- cachetools==5.3.3
3
- docx2txt==0.8
4
- fastapi==0.109.1
5
- llama-index-agent-openai==0.2.2
6
- llama-index-core==0.10.28
7
- llama-index-vector-stores-pinecone==0.1.3
8
- llama-index==0.10.28
9
- python-dotenv==1.0.0
10
- traceloop-sdk==0.15.11
11
- uvicorn==0.23.2