50 KiB
50 KiB
In [1]:
import requests
import zipfile
import io
# URL of the dataset
url = "https://archive.ics.uci.edu/static/public/228/sms+spam+collection.zip"
# Download the dataset
response = requests.get(url)
if response.status_code == 200:
print("Download successful")
else:
print("Failed to download the dataset")Download successful
In [2]:
# Extract the dataset
with zipfile.ZipFile(io.BytesIO(response.content)) as z:
z.extractall("sms_spam_collection")
print("Extraction successful")
Extraction successful
In [4]:
import os
# List the extracted files
extracted_files = os.listdir("sms_spam_collection")
print("Extracted files:", extracted_files)
Extracted files: ['SMSSpamCollection', 'readme']
In [5]:
import pandas as pd
# Load the dataset
df = pd.read_csv(
"sms_spam_collection/SMSSpamCollection",
sep="\t",
header=None,
names=["label", "message"],
)
In [6]:
# Display basic information about the dataset
print("-------------------- HEAD --------------------")
print(df.head())
print("-------------------- DESCRIBE --------------------")
print(df.describe())
print("-------------------- INFO --------------------")
print(df.info())
-------------------- HEAD --------------------
label message
0 ham Go until jurong point, crazy.. Available only ...
1 ham Ok lar... Joking wif u oni...
2 spam Free entry in 2 a wkly comp to win FA Cup fina...
3 ham U dun say so early hor... U c already then say...
4 ham Nah I don't think he goes to usf, he lives aro...
-------------------- DESCRIBE --------------------
label message
count 5572 5572
unique 2 5169
top ham Sorry, I'll call later
freq 4825 30
-------------------- INFO --------------------
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5572 entries, 0 to 5571
Data columns (total 2 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 label 5572 non-null object
1 message 5572 non-null object
dtypes: object(2)
memory usage: 87.2+ KB
None
In [7]:
# Check for missing values
print("Missing values:\n", df.isnull().sum())
Missing values: label 0 message 0 dtype: int64
In [8]:
# Check for duplicates
print("Duplicate entries:", df.duplicated().sum())
# Remove duplicates if any
df = df.drop_duplicates()
Duplicate entries: 403
In [10]:
import nltk
# Download the necessary NLTK data files
nltk.download("punkt")
nltk.download("punkt_tab")
nltk.download("stopwords")
print("=== BEFORE ANY PREPROCESSING ===")
print(df.head(5))
[nltk_data] Downloading package punkt to /home/jeremy/nltk_data... [nltk_data] Unzipping tokenizers/punkt.zip. [nltk_data] Downloading package punkt_tab to /home/jeremy/nltk_data... [nltk_data] Unzipping tokenizers/punkt_tab.zip.
=== BEFORE ANY PREPROCESSING === label message 0 ham Go until jurong point, crazy.. Available only ... 1 ham Ok lar... Joking wif u oni... 2 spam Free entry in 2 a wkly comp to win FA Cup fina... 3 ham U dun say so early hor... U c already then say... 4 ham Nah I don't think he goes to usf, he lives aro...
[nltk_data] Downloading package stopwords to /home/jeremy/nltk_data... [nltk_data] Unzipping corpora/stopwords.zip.
In [11]:
# Convert all message text to lowercase
df["message"] = df["message"].str.lower()
print("\n=== AFTER LOWERCASING ===")
print(df["message"].head(5))
=== AFTER LOWERCASING === 0 go until jurong point, crazy.. available only ... 1 ok lar... joking wif u oni... 2 free entry in 2 a wkly comp to win fa cup fina... 3 u dun say so early hor... u c already then say... 4 nah i don't think he goes to usf, he lives aro... Name: message, dtype: object
In [12]:
import re
# Remove non-essential punctuation and numbers, keep useful symbols like $ and !
df["message"] = df["message"].apply(lambda x: re.sub(r"[^a-z\s$!]", "", x))
print("\n=== AFTER REMOVING PUNCTUATION & NUMBERS (except $ and !) ===")
print(df["message"].head(5))
=== AFTER REMOVING PUNCTUATION & NUMBERS (except $ and !) === 0 go until jurong point crazy available only in ... 1 ok lar joking wif u oni 2 free entry in a wkly comp to win fa cup final... 3 u dun say so early hor u c already then say 4 nah i dont think he goes to usf he lives aroun... Name: message, dtype: object
In [13]:
from nltk.tokenize import word_tokenize
# Split each message into individual tokens
df["message"] = df["message"].apply(word_tokenize)
print("\n=== AFTER TOKENIZATION ===")
print(df["message"].head(5))
=== AFTER TOKENIZATION === 0 [go, until, jurong, point, crazy, available, o... 1 [ok, lar, joking, wif, u, oni] 2 [free, entry, in, a, wkly, comp, to, win, fa, ... 3 [u, dun, say, so, early, hor, u, c, already, t... 4 [nah, i, dont, think, he, goes, to, usf, he, l... Name: message, dtype: object
In [14]:
from nltk.corpus import stopwords
# Define a set of English stop words and remove them from the tokens
stop_words = set(stopwords.words("english"))
df["message"] = df["message"].apply(lambda x: [word for word in x if word not in stop_words])
print("\n=== AFTER REMOVING STOP WORDS ===")
print(df["message"].head(5))
=== AFTER REMOVING STOP WORDS === 0 [go, jurong, point, crazy, available, bugis, n... 1 [ok, lar, joking, wif, u, oni] 2 [free, entry, wkly, comp, win, fa, cup, final,... 3 [u, dun, say, early, hor, u, c, already, say] 4 [nah, dont, think, goes, usf, lives, around, t... Name: message, dtype: object
In [15]:
from nltk.stem import PorterStemmer
# Stem each token to reduce words to their base form
stemmer = PorterStemmer()
df["message"] = df["message"].apply(lambda x: [stemmer.stem(word) for word in x])
print("\n=== AFTER STEMMING ===")
print(df["message"].head(5))
=== AFTER STEMMING === 0 [go, jurong, point, crazi, avail, bugi, n, gre... 1 [ok, lar, joke, wif, u, oni] 2 [free, entri, wkli, comp, win, fa, cup, final,... 3 [u, dun, say, earli, hor, u, c, alreadi, say] 4 [nah, dont, think, goe, usf, live, around, tho... Name: message, dtype: object
In [16]:
# Rejoin tokens into a single string for feature extraction
df["message"] = df["message"].apply(lambda x: " ".join(x))
print("\n=== AFTER JOINING TOKENS BACK INTO STRINGS ===")
print(df["message"].head(5))
=== AFTER JOINING TOKENS BACK INTO STRINGS === 0 go jurong point crazi avail bugi n great world... 1 ok lar joke wif u oni 2 free entri wkli comp win fa cup final tkt st m... 3 u dun say earli hor u c alreadi say 4 nah dont think goe usf live around though Name: message, dtype: object
In [19]:
from sklearn.feature_extraction.text import CountVectorizer
# Initialize CountVectorizer with bigrams, min_df, and max_df to focus on relevant terms
vectorizer = CountVectorizer(min_df=1, max_df=0.9, ngram_range=(1, 2))
# Fit and transform the message column
X = vectorizer.fit_transform(df["message"])
# Labels (target variable)
y = df["label"].apply(lambda x: 1 if x == "spam" else 0) # Converting labels to 1 and 0
In [22]:
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import Pipeline
# Build the pipeline by combining vectorization and classification
pipeline = Pipeline([
("vectorizer", vectorizer),
("classifier", MultinomialNB())
])In [23]:
# Define the parameter grid for hyperparameter tuning
param_grid = {
"classifier__alpha": [0.01, 0.1, 0.15, 0.2, 0.25, 0.5, 0.75, 1.0]
}
# Perform the grid search with 5-fold cross-validation and the F1-score as metric
grid_search = GridSearchCV(
pipeline,
param_grid,
cv=5,
scoring="f1"
)
# Fit the grid search on the full dataset
grid_search.fit(df["message"], y)
# Extract the best model identified by the grid search
best_model = grid_search.best_estimator_
print("Best model parameters:", grid_search.best_params_)
Best model parameters: {'classifier__alpha': 0.25}
In [24]:
# Example SMS messages for evaluation
new_messages = [
"Congratulations! You've won a $1000 Walmart gift card. Go to http://bit.ly/1234 to claim now.",
"Hey, are we still meeting up for lunch today?",
"Urgent! Your account has been compromised. Verify your details here: www.fakebank.com/verify",
"Reminder: Your appointment is scheduled for tomorrow at 10am.",
"FREE entry in a weekly competition to win an iPad. Just text WIN to 80085 now!",
]
In [25]:
import numpy as np
import re
# Preprocess function that mirrors the training-time preprocessing
def preprocess_message(message):
message = message.lower()
message = re.sub(r"[^a-z\s$!]", "", message)
tokens = word_tokenize(message)
tokens = [word for word in tokens if word not in stop_words]
tokens = [stemmer.stem(word) for word in tokens]
return " ".join(tokens)
In [26]:
# Preprocess and vectorize messages
processed_messages = [preprocess_message(msg) for msg in new_messages]
In [27]:
# Transform preprocessed messages into feature vectors
X_new = best_model.named_steps["vectorizer"].transform(processed_messages)
In [28]:
# Transform preprocessed messages into feature vectors
X_new = best_model.named_steps["vectorizer"].transform(processed_messages)
In [29]:
# Predict with the trained classifier
predictions = best_model.named_steps["classifier"].predict(X_new)
prediction_probabilities = best_model.named_steps["classifier"].predict_proba(X_new)
In [30]:
# Display predictions and probabilities for each evaluated message
for i, msg in enumerate(new_messages):
prediction = "Spam" if predictions[i] == 1 else "Not-Spam"
spam_probability = prediction_probabilities[i][1] # Probability of being spam
ham_probability = prediction_probabilities[i][0] # Probability of being not spam
print(f"Message: {msg}")
print(f"Prediction: {prediction}")
print(f"Spam Probability: {spam_probability:.2f}")
print(f"Not-Spam Probability: {ham_probability:.2f}")
print("-" * 50)
Message: Congratulations! You've won a $1000 Walmart gift card. Go to http://bit.ly/1234 to claim now. Prediction: Spam Spam Probability: 1.00 Not-Spam Probability: 0.00 -------------------------------------------------- Message: Hey, are we still meeting up for lunch today? Prediction: Not-Spam Spam Probability: 0.00 Not-Spam Probability: 1.00 -------------------------------------------------- Message: Urgent! Your account has been compromised. Verify your details here: www.fakebank.com/verify Prediction: Spam Spam Probability: 0.96 Not-Spam Probability: 0.04 -------------------------------------------------- Message: Reminder: Your appointment is scheduled for tomorrow at 10am. Prediction: Not-Spam Spam Probability: 0.00 Not-Spam Probability: 1.00 -------------------------------------------------- Message: FREE entry in a weekly competition to win an iPad. Just text WIN to 80085 now! Prediction: Spam Spam Probability: 1.00 Not-Spam Probability: 0.00 --------------------------------------------------
In [31]:
import joblib
# Save the trained model to a file for future use
model_filename = 'spam_detection_model.joblib'
joblib.dump(best_model, model_filename)
print(f"Model saved to {model_filename}")
Model saved to spam_detection_model.joblib
In [32]:
# Load the saved model
loaded_model = joblib.load(model_filename)
# Preprocess new messages before prediction
new_data_processed = [preprocess_message(msg) for msg in new_messages]
# Make predictions on the preprocessed data
predictions = loaded_model.predict(new_data_processed)
In [34]:
import requests
import json
# Define the URL of the API endpoint
url = "http://localhost:8000/api/upload"
# Path to the model file you want to upload
model_file_path = "spam_detection_model.joblib"
# Open the file in binary mode and send the POST request
with open(model_file_path, "rb") as model_file:
files = {"model": model_file}
response = requests.post(url, files=files)
# Pretty print the response from the server
print(json.dumps(response.json(), indent=4))
[31m---------------------------------------------------------------------------[39m [31mConnectionRefusedError[39m Traceback (most recent call last) [36mFile [39m[32m~/.conda/envs/ai/lib/python3.11/site-packages/urllib3/connection.py:198[39m, in [36mHTTPConnection._new_conn[39m[34m(self)[39m [32m 197[39m [38;5;28;01mtry[39;00m: [32m--> [39m[32m198[39m sock = [43mconnection[49m[43m.[49m[43mcreate_connection[49m[43m([49m [32m 199[39m [43m [49m[43m([49m[38;5;28;43mself[39;49m[43m.[49m[43m_dns_host[49m[43m,[49m[43m [49m[38;5;28;43mself[39;49m[43m.[49m[43mport[49m[43m)[49m[43m,[49m [32m 200[39m [43m [49m[38;5;28;43mself[39;49m[43m.[49m[43mtimeout[49m[43m,[49m [32m 201[39m [43m [49m[43msource_address[49m[43m=[49m[38;5;28;43mself[39;49m[43m.[49m[43msource_address[49m[43m,[49m [32m 202[39m [43m [49m[43msocket_options[49m[43m=[49m[38;5;28;43mself[39;49m[43m.[49m[43msocket_options[49m[43m,[49m [32m 203[39m [43m [49m[43m)[49m [32m 204[39m [38;5;28;01mexcept[39;00m socket.gaierror [38;5;28;01mas[39;00m e: [36mFile [39m[32m~/.conda/envs/ai/lib/python3.11/site-packages/urllib3/util/connection.py:85[39m, in [36mcreate_connection[39m[34m(address, timeout, source_address, socket_options)[39m [32m 84[39m [38;5;28;01mtry[39;00m: [32m---> [39m[32m85[39m [38;5;28;01mraise[39;00m err [32m 86[39m [38;5;28;01mfinally[39;00m: [32m 87[39m [38;5;66;03m# Break explicitly a reference cycle[39;00m [36mFile [39m[32m~/.conda/envs/ai/lib/python3.11/site-packages/urllib3/util/connection.py:73[39m, in [36mcreate_connection[39m[34m(address, timeout, source_address, socket_options)[39m [32m 72[39m sock.bind(source_address) [32m---> [39m[32m73[39m [43msock[49m[43m.[49m[43mconnect[49m[43m([49m[43msa[49m[43m)[49m [32m 74[39m [38;5;66;03m# Break explicitly a reference cycle[39;00m [31mConnectionRefusedError[39m: [Errno 111] Connection refused The above exception was the direct cause of the following exception: [31mNewConnectionError[39m Traceback (most recent call last) [36mFile [39m[32m~/.conda/envs/ai/lib/python3.11/site-packages/urllib3/connectionpool.py:787[39m, in [36mHTTPConnectionPool.urlopen[39m[34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)[39m [32m 786[39m [38;5;66;03m# Make the request on the HTTPConnection object[39;00m [32m--> [39m[32m787[39m response = [38;5;28;43mself[39;49m[43m.[49m[43m_make_request[49m[43m([49m [32m 788[39m [43m [49m[43mconn[49m[43m,[49m [32m 789[39m [43m [49m[43mmethod[49m[43m,[49m [32m 790[39m [43m [49m[43murl[49m[43m,[49m [32m 791[39m [43m [49m[43mtimeout[49m[43m=[49m[43mtimeout_obj[49m[43m,[49m [32m 792[39m [43m [49m[43mbody[49m[43m=[49m[43mbody[49m[43m,[49m [32m 793[39m [43m [49m[43mheaders[49m[43m=[49m[43mheaders[49m[43m,[49m [32m 794[39m [43m [49m[43mchunked[49m[43m=[49m[43mchunked[49m[43m,[49m [32m 795[39m [43m [49m[43mretries[49m[43m=[49m[43mretries[49m[43m,[49m [32m 796[39m [43m [49m[43mresponse_conn[49m[43m=[49m[43mresponse_conn[49m[43m,[49m [32m 797[39m [43m [49m[43mpreload_content[49m[43m=[49m[43mpreload_content[49m[43m,[49m [32m 798[39m [43m [49m[43mdecode_content[49m[43m=[49m[43mdecode_content[49m[43m,[49m [32m 799[39m [43m [49m[43m*[49m[43m*[49m[43mresponse_kw[49m[43m,[49m [32m 800[39m [43m[49m[43m)[49m [32m 802[39m [38;5;66;03m# Everything went great![39;00m [36mFile [39m[32m~/.conda/envs/ai/lib/python3.11/site-packages/urllib3/connectionpool.py:493[39m, in [36mHTTPConnectionPool._make_request[39m[34m(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)[39m [32m 492[39m [38;5;28;01mtry[39;00m: [32m--> [39m[32m493[39m [43mconn[49m[43m.[49m[43mrequest[49m[43m([49m [32m 494[39m [43m [49m[43mmethod[49m[43m,[49m [32m 495[39m [43m [49m[43murl[49m[43m,[49m [32m 496[39m [43m [49m[43mbody[49m[43m=[49m[43mbody[49m[43m,[49m [32m 497[39m [43m [49m[43mheaders[49m[43m=[49m[43mheaders[49m[43m,[49m [32m 498[39m [43m [49m[43mchunked[49m[43m=[49m[43mchunked[49m[43m,[49m [32m 499[39m [43m [49m[43mpreload_content[49m[43m=[49m[43mpreload_content[49m[43m,[49m [32m 500[39m [43m [49m[43mdecode_content[49m[43m=[49m[43mdecode_content[49m[43m,[49m [32m 501[39m [43m [49m[43menforce_content_length[49m[43m=[49m[43menforce_content_length[49m[43m,[49m [32m 502[39m [43m [49m[43m)[49m [32m 504[39m [38;5;66;03m# We are swallowing BrokenPipeError (errno.EPIPE) since the server is[39;00m [32m 505[39m [38;5;66;03m# legitimately able to close the connection after sending a valid response.[39;00m [32m 506[39m [38;5;66;03m# With this behaviour, the received response is still readable.[39;00m [36mFile [39m[32m~/.conda/envs/ai/lib/python3.11/site-packages/urllib3/connection.py:494[39m, in [36mHTTPConnection.request[39m[34m(self, method, url, body, headers, chunked, preload_content, decode_content, enforce_content_length)[39m [32m 493[39m [38;5;28mself[39m.putheader(header, value) [32m--> [39m[32m494[39m [38;5;28;43mself[39;49m[43m.[49m[43mendheaders[49m[43m([49m[43m)[49m [32m 496[39m [38;5;66;03m# If we're given a body we start sending that in chunks.[39;00m [36mFile [39m[32m~/.conda/envs/ai/lib/python3.11/http/client.py:1281[39m, in [36mHTTPConnection.endheaders[39m[34m(self, message_body, encode_chunked)[39m [32m 1280[39m [38;5;28;01mraise[39;00m CannotSendHeader() [32m-> [39m[32m1281[39m [38;5;28;43mself[39;49m[43m.[49m[43m_send_output[49m[43m([49m[43mmessage_body[49m[43m,[49m[43m [49m[43mencode_chunked[49m[43m=[49m[43mencode_chunked[49m[43m)[49m [36mFile [39m[32m~/.conda/envs/ai/lib/python3.11/http/client.py:1041[39m, in [36mHTTPConnection._send_output[39m[34m(self, message_body, encode_chunked)[39m [32m 1040[39m [38;5;28;01mdel[39;00m [38;5;28mself[39m._buffer[:] [32m-> [39m[32m1041[39m [38;5;28;43mself[39;49m[43m.[49m[43msend[49m[43m([49m[43mmsg[49m[43m)[49m [32m 1043[39m [38;5;28;01mif[39;00m message_body [38;5;129;01mis[39;00m [38;5;129;01mnot[39;00m [38;5;28;01mNone[39;00m: [32m 1044[39m [32m 1045[39m [38;5;66;03m# create a consistent interface to message_body[39;00m [36mFile [39m[32m~/.conda/envs/ai/lib/python3.11/http/client.py:979[39m, in [36mHTTPConnection.send[39m[34m(self, data)[39m [32m 978[39m [38;5;28;01mif[39;00m [38;5;28mself[39m.auto_open: [32m--> [39m[32m979[39m [38;5;28;43mself[39;49m[43m.[49m[43mconnect[49m[43m([49m[43m)[49m [32m 980[39m [38;5;28;01melse[39;00m: [36mFile [39m[32m~/.conda/envs/ai/lib/python3.11/site-packages/urllib3/connection.py:325[39m, in [36mHTTPConnection.connect[39m[34m(self)[39m [32m 324[39m [38;5;28;01mdef[39;00m[38;5;250m [39m[34mconnect[39m([38;5;28mself[39m) -> [38;5;28;01mNone[39;00m: [32m--> [39m[32m325[39m [38;5;28mself[39m.sock = [38;5;28;43mself[39;49m[43m.[49m[43m_new_conn[49m[43m([49m[43m)[49m [32m 326[39m [38;5;28;01mif[39;00m [38;5;28mself[39m._tunnel_host: [32m 327[39m [38;5;66;03m# If we're tunneling it means we're connected to our proxy.[39;00m [36mFile [39m[32m~/.conda/envs/ai/lib/python3.11/site-packages/urllib3/connection.py:213[39m, in [36mHTTPConnection._new_conn[39m[34m(self)[39m [32m 212[39m [38;5;28;01mexcept[39;00m [38;5;167;01mOSError[39;00m [38;5;28;01mas[39;00m e: [32m--> [39m[32m213[39m [38;5;28;01mraise[39;00m NewConnectionError( [32m 214[39m [38;5;28mself[39m, [33mf[39m[33m"[39m[33mFailed to establish a new connection: [39m[38;5;132;01m{[39;00me[38;5;132;01m}[39;00m[33m"[39m [32m 215[39m ) [38;5;28;01mfrom[39;00m[38;5;250m [39m[34;01me[39;00m [32m 217[39m sys.audit([33m"[39m[33mhttp.client.connect[39m[33m"[39m, [38;5;28mself[39m, [38;5;28mself[39m.host, [38;5;28mself[39m.port) [31mNewConnectionError[39m: <urllib3.connection.HTTPConnection object at 0x7fcadf6b8c10>: Failed to establish a new connection: [Errno 111] Connection refused The above exception was the direct cause of the following exception: [31mMaxRetryError[39m Traceback (most recent call last) [36mFile [39m[32m~/.conda/envs/ai/lib/python3.11/site-packages/requests/adapters.py:644[39m, in [36mHTTPAdapter.send[39m[34m(self, request, stream, timeout, verify, cert, proxies)[39m [32m 643[39m [38;5;28;01mtry[39;00m: [32m--> [39m[32m644[39m resp = [43mconn[49m[43m.[49m[43murlopen[49m[43m([49m [32m 645[39m [43m [49m[43mmethod[49m[43m=[49m[43mrequest[49m[43m.[49m[43mmethod[49m[43m,[49m [32m 646[39m [43m [49m[43murl[49m[43m=[49m[43murl[49m[43m,[49m [32m 647[39m [43m [49m[43mbody[49m[43m=[49m[43mrequest[49m[43m.[49m[43mbody[49m[43m,[49m [32m 648[39m [43m [49m[43mheaders[49m[43m=[49m[43mrequest[49m[43m.[49m[43mheaders[49m[43m,[49m [32m 649[39m [43m [49m[43mredirect[49m[43m=[49m[38;5;28;43;01mFalse[39;49;00m[43m,[49m [32m 650[39m [43m [49m[43massert_same_host[49m[43m=[49m[38;5;28;43;01mFalse[39;49;00m[43m,[49m [32m 651[39m [43m [49m[43mpreload_content[49m[43m=[49m[38;5;28;43;01mFalse[39;49;00m[43m,[49m [32m 652[39m [43m [49m[43mdecode_content[49m[43m=[49m[38;5;28;43;01mFalse[39;49;00m[43m,[49m [32m 653[39m [43m [49m[43mretries[49m[43m=[49m[38;5;28;43mself[39;49m[43m.[49m[43mmax_retries[49m[43m,[49m [32m 654[39m [43m [49m[43mtimeout[49m[43m=[49m[43mtimeout[49m[43m,[49m [32m 655[39m [43m [49m[43mchunked[49m[43m=[49m[43mchunked[49m[43m,[49m [32m 656[39m [43m [49m[43m)[49m [32m 658[39m [38;5;28;01mexcept[39;00m (ProtocolError, [38;5;167;01mOSError[39;00m) [38;5;28;01mas[39;00m err: [36mFile [39m[32m~/.conda/envs/ai/lib/python3.11/site-packages/urllib3/connectionpool.py:841[39m, in [36mHTTPConnectionPool.urlopen[39m[34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)[39m [32m 839[39m new_e = ProtocolError([33m"[39m[33mConnection aborted.[39m[33m"[39m, new_e) [32m--> [39m[32m841[39m retries = [43mretries[49m[43m.[49m[43mincrement[49m[43m([49m [32m 842[39m [43m [49m[43mmethod[49m[43m,[49m[43m [49m[43murl[49m[43m,[49m[43m [49m[43merror[49m[43m=[49m[43mnew_e[49m[43m,[49m[43m [49m[43m_pool[49m[43m=[49m[38;5;28;43mself[39;49m[43m,[49m[43m [49m[43m_stacktrace[49m[43m=[49m[43msys[49m[43m.[49m[43mexc_info[49m[43m([49m[43m)[49m[43m[[49m[32;43m2[39;49m[43m][49m [32m 843[39m [43m[49m[43m)[49m [32m 844[39m retries.sleep() [36mFile [39m[32m~/.conda/envs/ai/lib/python3.11/site-packages/urllib3/util/retry.py:519[39m, in [36mRetry.increment[39m[34m(self, method, url, response, error, _pool, _stacktrace)[39m [32m 518[39m reason = error [38;5;129;01mor[39;00m ResponseError(cause) [32m--> [39m[32m519[39m [38;5;28;01mraise[39;00m MaxRetryError(_pool, url, reason) [38;5;28;01mfrom[39;00m[38;5;250m [39m[34;01mreason[39;00m [38;5;66;03m# type: ignore[arg-type][39;00m [32m 521[39m log.debug([33m"[39m[33mIncremented Retry for (url=[39m[33m'[39m[38;5;132;01m%s[39;00m[33m'[39m[33m): [39m[38;5;132;01m%r[39;00m[33m"[39m, url, new_retry) [31mMaxRetryError[39m: HTTPConnectionPool(host='localhost', port=8000): Max retries exceeded with url: /api/upload (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fcadf6b8c10>: Failed to establish a new connection: [Errno 111] Connection refused')) During handling of the above exception, another exception occurred: [31mConnectionError[39m Traceback (most recent call last) [36mCell[39m[36m [39m[32mIn[34][39m[32m, line 13[39m [32m 11[39m [38;5;28;01mwith[39;00m [38;5;28mopen[39m(model_file_path, [33m"[39m[33mrb[39m[33m"[39m) [38;5;28;01mas[39;00m model_file: [32m 12[39m files = {[33m"[39m[33mmodel[39m[33m"[39m: model_file} [32m---> [39m[32m13[39m response = [43mrequests[49m[43m.[49m[43mpost[49m[43m([49m[43murl[49m[43m,[49m[43m [49m[43mfiles[49m[43m=[49m[43mfiles[49m[43m)[49m [32m 15[39m [38;5;66;03m# Pretty print the response from the server[39;00m [32m 16[39m [38;5;28mprint[39m(json.dumps(response.json(), indent=[32m4[39m)) [36mFile [39m[32m~/.conda/envs/ai/lib/python3.11/site-packages/requests/api.py:115[39m, in [36mpost[39m[34m(url, data, json, **kwargs)[39m [32m 103[39m [38;5;28;01mdef[39;00m[38;5;250m [39m[34mpost[39m(url, data=[38;5;28;01mNone[39;00m, json=[38;5;28;01mNone[39;00m, **kwargs): [32m 104[39m [38;5;250m [39m[33mr[39m[33;03m"""Sends a POST request.[39;00m [32m 105[39m [32m 106[39m [33;03m :param url: URL for the new :class:`Request` object.[39;00m [32m (...)[39m[32m 112[39m [33;03m :rtype: requests.Response[39;00m [32m 113[39m [33;03m """[39;00m [32m--> [39m[32m115[39m [38;5;28;01mreturn[39;00m [43mrequest[49m[43m([49m[33;43m"[39;49m[33;43mpost[39;49m[33;43m"[39;49m[43m,[49m[43m [49m[43murl[49m[43m,[49m[43m [49m[43mdata[49m[43m=[49m[43mdata[49m[43m,[49m[43m [49m[43mjson[49m[43m=[49m[43mjson[49m[43m,[49m[43m [49m[43m*[49m[43m*[49m[43mkwargs[49m[43m)[49m [36mFile [39m[32m~/.conda/envs/ai/lib/python3.11/site-packages/requests/api.py:59[39m, in [36mrequest[39m[34m(method, url, **kwargs)[39m [32m 55[39m [38;5;66;03m# By using the 'with' statement we are sure the session is closed, thus we[39;00m [32m 56[39m [38;5;66;03m# avoid leaving sockets open which can trigger a ResourceWarning in some[39;00m [32m 57[39m [38;5;66;03m# cases, and look like a memory leak in others.[39;00m [32m 58[39m [38;5;28;01mwith[39;00m sessions.Session() [38;5;28;01mas[39;00m session: [32m---> [39m[32m59[39m [38;5;28;01mreturn[39;00m [43msession[49m[43m.[49m[43mrequest[49m[43m([49m[43mmethod[49m[43m=[49m[43mmethod[49m[43m,[49m[43m [49m[43murl[49m[43m=[49m[43murl[49m[43m,[49m[43m [49m[43m*[49m[43m*[49m[43mkwargs[49m[43m)[49m [36mFile [39m[32m~/.conda/envs/ai/lib/python3.11/site-packages/requests/sessions.py:589[39m, in [36mSession.request[39m[34m(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)[39m [32m 584[39m send_kwargs = { [32m 585[39m [33m"[39m[33mtimeout[39m[33m"[39m: timeout, [32m 586[39m [33m"[39m[33mallow_redirects[39m[33m"[39m: allow_redirects, [32m 587[39m } [32m 588[39m send_kwargs.update(settings) [32m--> [39m[32m589[39m resp = [38;5;28;43mself[39;49m[43m.[49m[43msend[49m[43m([49m[43mprep[49m[43m,[49m[43m [49m[43m*[49m[43m*[49m[43msend_kwargs[49m[43m)[49m [32m 591[39m [38;5;28;01mreturn[39;00m resp [36mFile [39m[32m~/.conda/envs/ai/lib/python3.11/site-packages/requests/sessions.py:703[39m, in [36mSession.send[39m[34m(self, request, **kwargs)[39m [32m 700[39m start = preferred_clock() [32m 702[39m [38;5;66;03m# Send the request[39;00m [32m--> [39m[32m703[39m r = [43madapter[49m[43m.[49m[43msend[49m[43m([49m[43mrequest[49m[43m,[49m[43m [49m[43m*[49m[43m*[49m[43mkwargs[49m[43m)[49m [32m 705[39m [38;5;66;03m# Total elapsed time of the request (approximately)[39;00m [32m 706[39m elapsed = preferred_clock() - start [36mFile [39m[32m~/.conda/envs/ai/lib/python3.11/site-packages/requests/adapters.py:677[39m, in [36mHTTPAdapter.send[39m[34m(self, request, stream, timeout, verify, cert, proxies)[39m [32m 673[39m [38;5;28;01mif[39;00m [38;5;28misinstance[39m(e.reason, _SSLError): [32m 674[39m [38;5;66;03m# This branch is for urllib3 v1.22 and later.[39;00m [32m 675[39m [38;5;28;01mraise[39;00m SSLError(e, request=request) [32m--> [39m[32m677[39m [38;5;28;01mraise[39;00m [38;5;167;01mConnectionError[39;00m(e, request=request) [32m 679[39m [38;5;28;01mexcept[39;00m ClosedPoolError [38;5;28;01mas[39;00m e: [32m 680[39m [38;5;28;01mraise[39;00m [38;5;167;01mConnectionError[39;00m(e, request=request) [31mConnectionError[39m: HTTPConnectionPool(host='localhost', port=8000): Max retries exceeded with url: /api/upload (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fcadf6b8c10>: Failed to establish a new connection: [Errno 111] Connection refused'))
In [ ]: