{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "import json\n",
    "from typing import List\n",
    "from server import GoRequest, GoResponse, ETFin, ETFOut, LayerOut\n",
    "\n",
    "url_python = \"http://localhost:8000/optimize\"\n",
    "url_go = \"http://localhost:1323/optimize_portfolio\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# EIMI{}MI{}IE00BKM4GZ66{}italy{}iShares Core MSCI Emerging Markets IMI UCITS{}2014-07-24{}2023-01-05\n",
    "# EMH5{}MI{}IE00BP46NG52{}italy{}SPDR BofA Merrill Lynch 0-5 Emerging Markets Government Bond UCITS{}2016-02-23{}2023-01-05\n",
    "# GGOV{}PA{}LU1437016204{}france{}Amundi Index Solutions - Amundi Index J.P. Morgan GBI Global Govies{}2017-02-15{}2023-01-05\n",
    "# SWDA{}MI{}IE00B4L5Y983{}italy{}iShares Core MSCI World UCITS ETF USD (Acc){}2010-02-01{}2023-01-05\n",
    "\n",
    "etf1 = ETFin(\n",
    "    ticker=\"EIMI\",\n",
    "    isin=\"IE00BKM4GZ66\",\n",
    "    excange=\"italy\",\n",
    "    filename=\"EIMI{}MI{}IE00BKM4GZ66{}italy{}iShares Core MSCI Emerging Markets IMI UCITS{}2014-07-24{}2023-01-05.json\"\n",
    ")\n",
    "etf2 = ETFin(\n",
    "    ticker=\"EMH5\",\n",
    "    isin=\"IE00BP46NG52\",\n",
    "    excange=\"italy\",\n",
    "    filename=\"EMH5{}MI{}IE00BP46NG52{}italy{}SPDR BofA Merrill Lynch 0-5 Emerging Markets Government Bond UCITS{}2016-02-23{}2023-01-05.json\"\n",
    ")\n",
    "etf3 = ETFin(\n",
    "    ticker=\"GGOV\",\n",
    "    isin=\"LU1437016204\",\n",
    "    excange=\"france\",\n",
    "    filename=\"GGOV{}PA{}LU1437016204{}france{}Amundi Index Solutions - Amundi Index J.P. Morgan GBI Global Govies{}2017-02-15{}2023-01-05.json\"\n",
    ")\n",
    "etf4 = ETFin(\n",
    "    ticker=\"SWDA\",\n",
    "    isin=\"IE00B4L5Y983\",\n",
    "    excange=\"italy\",\n",
    "    filename=\"SWDA{}MI{}IE00B4L5Y983{}italy{}iShares Core MSCI World UCITS ETF USD (Acc){}2010-02-01{}2023-01-05.json\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "ename": "ConnectionError",
     "evalue": "('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mRemoteDisconnected\u001b[0m                        Traceback (most recent call last)",
      "File \u001b[0;32m/usr/lib/python3/dist-packages/urllib3/connectionpool.py:699\u001b[0m, in \u001b[0;36mHTTPConnectionPool.urlopen\u001b[0;34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)\u001b[0m\n\u001b[1;32m    698\u001b[0m \u001b[39m# Make the request on the httplib connection object.\u001b[39;00m\n\u001b[0;32m--> 699\u001b[0m httplib_response \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_make_request(\n\u001b[1;32m    700\u001b[0m     conn,\n\u001b[1;32m    701\u001b[0m     method,\n\u001b[1;32m    702\u001b[0m     url,\n\u001b[1;32m    703\u001b[0m     timeout\u001b[39m=\u001b[39;49mtimeout_obj,\n\u001b[1;32m    704\u001b[0m     body\u001b[39m=\u001b[39;49mbody,\n\u001b[1;32m    705\u001b[0m     headers\u001b[39m=\u001b[39;49mheaders,\n\u001b[1;32m    706\u001b[0m     chunked\u001b[39m=\u001b[39;49mchunked,\n\u001b[1;32m    707\u001b[0m )\n\u001b[1;32m    709\u001b[0m \u001b[39m# If we're going to release the connection in ``finally:``, then\u001b[39;00m\n\u001b[1;32m    710\u001b[0m \u001b[39m# the response doesn't need to know about the connection. Otherwise\u001b[39;00m\n\u001b[1;32m    711\u001b[0m \u001b[39m# it will also try to release it and we'll have a double-release\u001b[39;00m\n\u001b[1;32m    712\u001b[0m \u001b[39m# mess.\u001b[39;00m\n",
      "File \u001b[0;32m/usr/lib/python3/dist-packages/urllib3/connectionpool.py:445\u001b[0m, in \u001b[0;36mHTTPConnectionPool._make_request\u001b[0;34m(self, conn, method, url, timeout, chunked, **httplib_request_kw)\u001b[0m\n\u001b[1;32m    441\u001b[0m         \u001b[39mexcept\u001b[39;00m \u001b[39mBaseException\u001b[39;00m \u001b[39mas\u001b[39;00m e:\n\u001b[1;32m    442\u001b[0m             \u001b[39m# Remove the TypeError from the exception chain in\u001b[39;00m\n\u001b[1;32m    443\u001b[0m             \u001b[39m# Python 3 (including for exceptions like SystemExit).\u001b[39;00m\n\u001b[1;32m    444\u001b[0m             \u001b[39m# Otherwise it looks like a bug in the code.\u001b[39;00m\n\u001b[0;32m--> 445\u001b[0m             six\u001b[39m.\u001b[39;49mraise_from(e, \u001b[39mNone\u001b[39;49;00m)\n\u001b[1;32m    446\u001b[0m \u001b[39mexcept\u001b[39;00m (SocketTimeout, BaseSSLError, SocketError) \u001b[39mas\u001b[39;00m e:\n",
      "File \u001b[0;32m<string>:3\u001b[0m, in \u001b[0;36mraise_from\u001b[0;34m(value, from_value)\u001b[0m\n",
      "File \u001b[0;32m/usr/lib/python3/dist-packages/urllib3/connectionpool.py:440\u001b[0m, in \u001b[0;36mHTTPConnectionPool._make_request\u001b[0;34m(self, conn, method, url, timeout, chunked, **httplib_request_kw)\u001b[0m\n\u001b[1;32m    439\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m--> 440\u001b[0m     httplib_response \u001b[39m=\u001b[39m conn\u001b[39m.\u001b[39;49mgetresponse()\n\u001b[1;32m    441\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mBaseException\u001b[39;00m \u001b[39mas\u001b[39;00m e:\n\u001b[1;32m    442\u001b[0m     \u001b[39m# Remove the TypeError from the exception chain in\u001b[39;00m\n\u001b[1;32m    443\u001b[0m     \u001b[39m# Python 3 (including for exceptions like SystemExit).\u001b[39;00m\n\u001b[1;32m    444\u001b[0m     \u001b[39m# Otherwise it looks like a bug in the code.\u001b[39;00m\n",
      "File \u001b[0;32m/usr/lib/python3.10/http/client.py:1374\u001b[0m, in \u001b[0;36mHTTPConnection.getresponse\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m   1373\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m-> 1374\u001b[0m     response\u001b[39m.\u001b[39;49mbegin()\n\u001b[1;32m   1375\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mConnectionError\u001b[39;00m:\n",
      "File \u001b[0;32m/usr/lib/python3.10/http/client.py:318\u001b[0m, in \u001b[0;36mHTTPResponse.begin\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    317\u001b[0m \u001b[39mwhile\u001b[39;00m \u001b[39mTrue\u001b[39;00m:\n\u001b[0;32m--> 318\u001b[0m     version, status, reason \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_read_status()\n\u001b[1;32m    319\u001b[0m     \u001b[39mif\u001b[39;00m status \u001b[39m!=\u001b[39m CONTINUE:\n",
      "File \u001b[0;32m/usr/lib/python3.10/http/client.py:287\u001b[0m, in \u001b[0;36mHTTPResponse._read_status\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    284\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m line:\n\u001b[1;32m    285\u001b[0m     \u001b[39m# Presumably, the server closed the connection before\u001b[39;00m\n\u001b[1;32m    286\u001b[0m     \u001b[39m# sending a valid response.\u001b[39;00m\n\u001b[0;32m--> 287\u001b[0m     \u001b[39mraise\u001b[39;00m RemoteDisconnected(\u001b[39m\"\u001b[39m\u001b[39mRemote end closed connection without\u001b[39m\u001b[39m\"\u001b[39m\n\u001b[1;32m    288\u001b[0m                              \u001b[39m\"\u001b[39m\u001b[39m response\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[1;32m    289\u001b[0m \u001b[39mtry\u001b[39;00m:\n",
      "\u001b[0;31mRemoteDisconnected\u001b[0m: Remote end closed connection without response",
      "\nDuring handling of the above exception, another exception occurred:\n",
      "\u001b[0;31mProtocolError\u001b[0m                             Traceback (most recent call last)",
      "File \u001b[0;32m/usr/lib/python3/dist-packages/requests/adapters.py:439\u001b[0m, in \u001b[0;36mHTTPAdapter.send\u001b[0;34m(self, request, stream, timeout, verify, cert, proxies)\u001b[0m\n\u001b[1;32m    438\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m chunked:\n\u001b[0;32m--> 439\u001b[0m     resp \u001b[39m=\u001b[39m conn\u001b[39m.\u001b[39;49murlopen(\n\u001b[1;32m    440\u001b[0m         method\u001b[39m=\u001b[39;49mrequest\u001b[39m.\u001b[39;49mmethod,\n\u001b[1;32m    441\u001b[0m         url\u001b[39m=\u001b[39;49murl,\n\u001b[1;32m    442\u001b[0m         body\u001b[39m=\u001b[39;49mrequest\u001b[39m.\u001b[39;49mbody,\n\u001b[1;32m    443\u001b[0m         headers\u001b[39m=\u001b[39;49mrequest\u001b[39m.\u001b[39;49mheaders,\n\u001b[1;32m    444\u001b[0m         redirect\u001b[39m=\u001b[39;49m\u001b[39mFalse\u001b[39;49;00m,\n\u001b[1;32m    445\u001b[0m         assert_same_host\u001b[39m=\u001b[39;49m\u001b[39mFalse\u001b[39;49;00m,\n\u001b[1;32m    446\u001b[0m         preload_content\u001b[39m=\u001b[39;49m\u001b[39mFalse\u001b[39;49;00m,\n\u001b[1;32m    447\u001b[0m         decode_content\u001b[39m=\u001b[39;49m\u001b[39mFalse\u001b[39;49;00m,\n\u001b[1;32m    448\u001b[0m         retries\u001b[39m=\u001b[39;49m\u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mmax_retries,\n\u001b[1;32m    449\u001b[0m         timeout\u001b[39m=\u001b[39;49mtimeout\n\u001b[1;32m    450\u001b[0m     )\n\u001b[1;32m    452\u001b[0m \u001b[39m# Send the request.\u001b[39;00m\n\u001b[1;32m    453\u001b[0m \u001b[39melse\u001b[39;00m:\n",
      "File \u001b[0;32m/usr/lib/python3/dist-packages/urllib3/connectionpool.py:755\u001b[0m, in \u001b[0;36mHTTPConnectionPool.urlopen\u001b[0;34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)\u001b[0m\n\u001b[1;32m    753\u001b[0m     e \u001b[39m=\u001b[39m ProtocolError(\u001b[39m\"\u001b[39m\u001b[39mConnection aborted.\u001b[39m\u001b[39m\"\u001b[39m, e)\n\u001b[0;32m--> 755\u001b[0m retries \u001b[39m=\u001b[39m retries\u001b[39m.\u001b[39;49mincrement(\n\u001b[1;32m    756\u001b[0m     method, url, error\u001b[39m=\u001b[39;49me, _pool\u001b[39m=\u001b[39;49m\u001b[39mself\u001b[39;49m, _stacktrace\u001b[39m=\u001b[39;49msys\u001b[39m.\u001b[39;49mexc_info()[\u001b[39m2\u001b[39;49m]\n\u001b[1;32m    757\u001b[0m )\n\u001b[1;32m    758\u001b[0m retries\u001b[39m.\u001b[39msleep()\n",
      "File \u001b[0;32m/usr/lib/python3/dist-packages/urllib3/util/retry.py:532\u001b[0m, in \u001b[0;36mRetry.increment\u001b[0;34m(self, method, url, response, error, _pool, _stacktrace)\u001b[0m\n\u001b[1;32m    531\u001b[0m \u001b[39mif\u001b[39;00m read \u001b[39mis\u001b[39;00m \u001b[39mFalse\u001b[39;00m \u001b[39mor\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_is_method_retryable(method):\n\u001b[0;32m--> 532\u001b[0m     \u001b[39mraise\u001b[39;00m six\u001b[39m.\u001b[39;49mreraise(\u001b[39mtype\u001b[39;49m(error), error, _stacktrace)\n\u001b[1;32m    533\u001b[0m \u001b[39melif\u001b[39;00m read \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n",
      "File \u001b[0;32m/usr/lib/python3/dist-packages/six.py:718\u001b[0m, in \u001b[0;36mreraise\u001b[0;34m(tp, value, tb)\u001b[0m\n\u001b[1;32m    717\u001b[0m \u001b[39mif\u001b[39;00m value\u001b[39m.\u001b[39m__traceback__ \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m tb:\n\u001b[0;32m--> 718\u001b[0m     \u001b[39mraise\u001b[39;00m value\u001b[39m.\u001b[39mwith_traceback(tb)\n\u001b[1;32m    719\u001b[0m \u001b[39mraise\u001b[39;00m value\n",
      "File \u001b[0;32m/usr/lib/python3/dist-packages/urllib3/connectionpool.py:699\u001b[0m, in \u001b[0;36mHTTPConnectionPool.urlopen\u001b[0;34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)\u001b[0m\n\u001b[1;32m    698\u001b[0m \u001b[39m# Make the request on the httplib connection object.\u001b[39;00m\n\u001b[0;32m--> 699\u001b[0m httplib_response \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_make_request(\n\u001b[1;32m    700\u001b[0m     conn,\n\u001b[1;32m    701\u001b[0m     method,\n\u001b[1;32m    702\u001b[0m     url,\n\u001b[1;32m    703\u001b[0m     timeout\u001b[39m=\u001b[39;49mtimeout_obj,\n\u001b[1;32m    704\u001b[0m     body\u001b[39m=\u001b[39;49mbody,\n\u001b[1;32m    705\u001b[0m     headers\u001b[39m=\u001b[39;49mheaders,\n\u001b[1;32m    706\u001b[0m     chunked\u001b[39m=\u001b[39;49mchunked,\n\u001b[1;32m    707\u001b[0m )\n\u001b[1;32m    709\u001b[0m \u001b[39m# If we're going to release the connection in ``finally:``, then\u001b[39;00m\n\u001b[1;32m    710\u001b[0m \u001b[39m# the response doesn't need to know about the connection. Otherwise\u001b[39;00m\n\u001b[1;32m    711\u001b[0m \u001b[39m# it will also try to release it and we'll have a double-release\u001b[39;00m\n\u001b[1;32m    712\u001b[0m \u001b[39m# mess.\u001b[39;00m\n",
      "File \u001b[0;32m/usr/lib/python3/dist-packages/urllib3/connectionpool.py:445\u001b[0m, in \u001b[0;36mHTTPConnectionPool._make_request\u001b[0;34m(self, conn, method, url, timeout, chunked, **httplib_request_kw)\u001b[0m\n\u001b[1;32m    441\u001b[0m         \u001b[39mexcept\u001b[39;00m \u001b[39mBaseException\u001b[39;00m \u001b[39mas\u001b[39;00m e:\n\u001b[1;32m    442\u001b[0m             \u001b[39m# Remove the TypeError from the exception chain in\u001b[39;00m\n\u001b[1;32m    443\u001b[0m             \u001b[39m# Python 3 (including for exceptions like SystemExit).\u001b[39;00m\n\u001b[1;32m    444\u001b[0m             \u001b[39m# Otherwise it looks like a bug in the code.\u001b[39;00m\n\u001b[0;32m--> 445\u001b[0m             six\u001b[39m.\u001b[39;49mraise_from(e, \u001b[39mNone\u001b[39;49;00m)\n\u001b[1;32m    446\u001b[0m \u001b[39mexcept\u001b[39;00m (SocketTimeout, BaseSSLError, SocketError) \u001b[39mas\u001b[39;00m e:\n",
      "File \u001b[0;32m<string>:3\u001b[0m, in \u001b[0;36mraise_from\u001b[0;34m(value, from_value)\u001b[0m\n",
      "File \u001b[0;32m/usr/lib/python3/dist-packages/urllib3/connectionpool.py:440\u001b[0m, in \u001b[0;36mHTTPConnectionPool._make_request\u001b[0;34m(self, conn, method, url, timeout, chunked, **httplib_request_kw)\u001b[0m\n\u001b[1;32m    439\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m--> 440\u001b[0m     httplib_response \u001b[39m=\u001b[39m conn\u001b[39m.\u001b[39;49mgetresponse()\n\u001b[1;32m    441\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mBaseException\u001b[39;00m \u001b[39mas\u001b[39;00m e:\n\u001b[1;32m    442\u001b[0m     \u001b[39m# Remove the TypeError from the exception chain in\u001b[39;00m\n\u001b[1;32m    443\u001b[0m     \u001b[39m# Python 3 (including for exceptions like SystemExit).\u001b[39;00m\n\u001b[1;32m    444\u001b[0m     \u001b[39m# Otherwise it looks like a bug in the code.\u001b[39;00m\n",
      "File \u001b[0;32m/usr/lib/python3.10/http/client.py:1374\u001b[0m, in \u001b[0;36mHTTPConnection.getresponse\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m   1373\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m-> 1374\u001b[0m     response\u001b[39m.\u001b[39;49mbegin()\n\u001b[1;32m   1375\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mConnectionError\u001b[39;00m:\n",
      "File \u001b[0;32m/usr/lib/python3.10/http/client.py:318\u001b[0m, in \u001b[0;36mHTTPResponse.begin\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    317\u001b[0m \u001b[39mwhile\u001b[39;00m \u001b[39mTrue\u001b[39;00m:\n\u001b[0;32m--> 318\u001b[0m     version, status, reason \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_read_status()\n\u001b[1;32m    319\u001b[0m     \u001b[39mif\u001b[39;00m status \u001b[39m!=\u001b[39m CONTINUE:\n",
      "File \u001b[0;32m/usr/lib/python3.10/http/client.py:287\u001b[0m, in \u001b[0;36mHTTPResponse._read_status\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    284\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m line:\n\u001b[1;32m    285\u001b[0m     \u001b[39m# Presumably, the server closed the connection before\u001b[39;00m\n\u001b[1;32m    286\u001b[0m     \u001b[39m# sending a valid response.\u001b[39;00m\n\u001b[0;32m--> 287\u001b[0m     \u001b[39mraise\u001b[39;00m RemoteDisconnected(\u001b[39m\"\u001b[39m\u001b[39mRemote end closed connection without\u001b[39m\u001b[39m\"\u001b[39m\n\u001b[1;32m    288\u001b[0m                              \u001b[39m\"\u001b[39m\u001b[39m response\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[1;32m    289\u001b[0m \u001b[39mtry\u001b[39;00m:\n",
      "\u001b[0;31mProtocolError\u001b[0m: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))",
      "\nDuring handling of the above exception, another exception occurred:\n",
      "\u001b[0;31mConnectionError\u001b[0m                           Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[3], line 8\u001b[0m\n\u001b[1;32m      1\u001b[0m opt_request \u001b[39m=\u001b[39m GoRequest(\n\u001b[1;32m      2\u001b[0m     etfs\u001b[39m=\u001b[39m[etf1, etf2, etf3, etf4],\n\u001b[1;32m      3\u001b[0m     prefer_recent_data\u001b[39m=\u001b[39m\u001b[39mFalse\u001b[39;00m,\n\u001b[1;32m      4\u001b[0m     min_weight\u001b[39m=\u001b[39m\u001b[39mfloat\u001b[39m(\u001b[39m0\u001b[39m),\n\u001b[1;32m      5\u001b[0m     num_layers\u001b[39m=\u001b[39m\u001b[39mint\u001b[39m(\u001b[39m3\u001b[39m)\n\u001b[1;32m      6\u001b[0m )\n\u001b[0;32m----> 8\u001b[0m response \u001b[39m=\u001b[39m requests\u001b[39m.\u001b[39;49mpost(url_go, json\u001b[39m=\u001b[39;49mopt_request\u001b[39m.\u001b[39;49mdict())\n",
      "File \u001b[0;32m/usr/lib/python3/dist-packages/requests/api.py:119\u001b[0m, in \u001b[0;36mpost\u001b[0;34m(url, data, json, **kwargs)\u001b[0m\n\u001b[1;32m    107\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mpost\u001b[39m(url, data\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, json\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwargs):\n\u001b[1;32m    108\u001b[0m     \u001b[39mr\u001b[39m\u001b[39m\"\"\"Sends a POST request.\u001b[39;00m\n\u001b[1;32m    109\u001b[0m \n\u001b[1;32m    110\u001b[0m \u001b[39m    :param url: URL for the new :class:`Request` object.\u001b[39;00m\n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m    116\u001b[0m \u001b[39m    :rtype: requests.Response\u001b[39;00m\n\u001b[1;32m    117\u001b[0m \u001b[39m    \"\"\"\u001b[39;00m\n\u001b[0;32m--> 119\u001b[0m     \u001b[39mreturn\u001b[39;00m request(\u001b[39m'\u001b[39;49m\u001b[39mpost\u001b[39;49m\u001b[39m'\u001b[39;49m, url, data\u001b[39m=\u001b[39;49mdata, json\u001b[39m=\u001b[39;49mjson, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n",
      "File \u001b[0;32m/usr/lib/python3/dist-packages/requests/api.py:61\u001b[0m, in \u001b[0;36mrequest\u001b[0;34m(method, url, **kwargs)\u001b[0m\n\u001b[1;32m     57\u001b[0m \u001b[39m# By using the 'with' statement we are sure the session is closed, thus we\u001b[39;00m\n\u001b[1;32m     58\u001b[0m \u001b[39m# avoid leaving sockets open which can trigger a ResourceWarning in some\u001b[39;00m\n\u001b[1;32m     59\u001b[0m \u001b[39m# cases, and look like a memory leak in others.\u001b[39;00m\n\u001b[1;32m     60\u001b[0m \u001b[39mwith\u001b[39;00m sessions\u001b[39m.\u001b[39mSession() \u001b[39mas\u001b[39;00m session:\n\u001b[0;32m---> 61\u001b[0m     \u001b[39mreturn\u001b[39;00m session\u001b[39m.\u001b[39;49mrequest(method\u001b[39m=\u001b[39;49mmethod, url\u001b[39m=\u001b[39;49murl, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n",
      "File \u001b[0;32m/usr/lib/python3/dist-packages/requests/sessions.py:542\u001b[0m, in \u001b[0;36mSession.request\u001b[0;34m(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)\u001b[0m\n\u001b[1;32m    537\u001b[0m send_kwargs \u001b[39m=\u001b[39m {\n\u001b[1;32m    538\u001b[0m     \u001b[39m'\u001b[39m\u001b[39mtimeout\u001b[39m\u001b[39m'\u001b[39m: timeout,\n\u001b[1;32m    539\u001b[0m     \u001b[39m'\u001b[39m\u001b[39mallow_redirects\u001b[39m\u001b[39m'\u001b[39m: allow_redirects,\n\u001b[1;32m    540\u001b[0m }\n\u001b[1;32m    541\u001b[0m send_kwargs\u001b[39m.\u001b[39mupdate(settings)\n\u001b[0;32m--> 542\u001b[0m resp \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49msend(prep, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49msend_kwargs)\n\u001b[1;32m    544\u001b[0m \u001b[39mreturn\u001b[39;00m resp\n",
      "File \u001b[0;32m/usr/lib/python3/dist-packages/requests/sessions.py:655\u001b[0m, in \u001b[0;36mSession.send\u001b[0;34m(self, request, **kwargs)\u001b[0m\n\u001b[1;32m    652\u001b[0m start \u001b[39m=\u001b[39m preferred_clock()\n\u001b[1;32m    654\u001b[0m \u001b[39m# Send the request\u001b[39;00m\n\u001b[0;32m--> 655\u001b[0m r \u001b[39m=\u001b[39m adapter\u001b[39m.\u001b[39;49msend(request, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m    657\u001b[0m \u001b[39m# Total elapsed time of the request (approximately)\u001b[39;00m\n\u001b[1;32m    658\u001b[0m elapsed \u001b[39m=\u001b[39m preferred_clock() \u001b[39m-\u001b[39m start\n",
      "File \u001b[0;32m/usr/lib/python3/dist-packages/requests/adapters.py:498\u001b[0m, in \u001b[0;36mHTTPAdapter.send\u001b[0;34m(self, request, stream, timeout, verify, cert, proxies)\u001b[0m\n\u001b[1;32m    495\u001b[0m             \u001b[39mraise\u001b[39;00m\n\u001b[1;32m    497\u001b[0m \u001b[39mexcept\u001b[39;00m (ProtocolError, socket\u001b[39m.\u001b[39merror) \u001b[39mas\u001b[39;00m err:\n\u001b[0;32m--> 498\u001b[0m     \u001b[39mraise\u001b[39;00m \u001b[39mConnectionError\u001b[39;00m(err, request\u001b[39m=\u001b[39mrequest)\n\u001b[1;32m    500\u001b[0m \u001b[39mexcept\u001b[39;00m MaxRetryError \u001b[39mas\u001b[39;00m e:\n\u001b[1;32m    501\u001b[0m     \u001b[39mif\u001b[39;00m \u001b[39misinstance\u001b[39m(e\u001b[39m.\u001b[39mreason, ConnectTimeoutError):\n\u001b[1;32m    502\u001b[0m         \u001b[39m# TODO: Remove this in 3.0.0: see #2811\u001b[39;00m\n",
      "\u001b[0;31mConnectionError\u001b[0m: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))"
     ]
    }
   ],
   "source": [
    "opt_request = GoRequest(\n",
    "    etfs=[etf1, etf2, etf3, etf4],\n",
    "    prefer_recent_data=False,\n",
    "    min_weight=float(0),\n",
    "    num_layers=int(3)\n",
    ")\n",
    "\n",
    "response = requests.post(url_go, json=opt_request.dict())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "response.status_code == 200"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "resp: List[List[ETFOut]] = response.json()['layers']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[\n",
      "    {\n",
      "        \"etfs\": [\n",
      "            {\n",
      "                \"ticker\": \"EIMI\",\n",
      "                \"isin\": \"IE00BKM4GZ66\",\n",
      "                \"excange\": \"italy\",\n",
      "                \"percent\": 3.3,\n",
      "                \"last_price\": 27.815\n",
      "            },\n",
      "            {\n",
      "                \"ticker\": \"EMH5\",\n",
      "                \"isin\": \"IE00BP46NG52\",\n",
      "                \"excange\": \"italy\",\n",
      "                \"percent\": 34.84,\n",
      "                \"last_price\": 25.065\n",
      "            },\n",
      "            {\n",
      "                \"ticker\": \"GGOV\",\n",
      "                \"isin\": \"LU1437016204\",\n",
      "                \"excange\": \"france\",\n",
      "                \"percent\": 58.39,\n",
      "                \"last_price\": 47.05\n",
      "            },\n",
      "            {\n",
      "                \"ticker\": \"SWDA\",\n",
      "                \"isin\": \"IE00B4L5Y983\",\n",
      "                \"excange\": \"italy\",\n",
      "                \"percent\": 3.47,\n",
      "                \"last_price\": 69.38\n",
      "            }\n",
      "        ],\n",
      "        \"risk\": 0.051729455520849864,\n",
      "        \"expected_return\": 0.00814539701488171,\n",
      "        \"sharpe_ratio\": 0.13813014157865466\n",
      "    },\n",
      "    {\n",
      "        \"etfs\": [\n",
      "            {\n",
      "                \"ticker\": \"EIMI\",\n",
      "                \"isin\": \"IE00BKM4GZ66\",\n",
      "                \"excange\": \"italy\",\n",
      "                \"percent\": 0.0,\n",
      "                \"last_price\": 27.815\n",
      "            },\n",
      "            {\n",
      "                \"ticker\": \"EMH5\",\n",
      "                \"isin\": \"IE00BP46NG52\",\n",
      "                \"excange\": \"italy\",\n",
      "                \"percent\": 32.03,\n",
      "                \"last_price\": 25.065\n",
      "            },\n",
      "            {\n",
      "                \"ticker\": \"GGOV\",\n",
      "                \"isin\": \"LU1437016204\",\n",
      "                \"excange\": \"france\",\n",
      "                \"percent\": 25.04,\n",
      "                \"last_price\": 47.05\n",
      "            },\n",
      "            {\n",
      "                \"ticker\": \"SWDA\",\n",
      "                \"isin\": \"IE00B4L5Y983\",\n",
      "                \"excange\": \"italy\",\n",
      "                \"percent\": 42.94,\n",
      "                \"last_price\": 69.38\n",
      "            }\n",
      "        ],\n",
      "        \"risk\": 0.08633311621506369,\n",
      "        \"expected_return\": 0.05844649722173568,\n",
      "        \"sharpe_ratio\": 0.6654051161391094\n",
      "    },\n",
      "    {\n",
      "        \"etfs\": [\n",
      "            {\n",
      "                \"ticker\": \"EIMI\",\n",
      "                \"isin\": \"IE00BKM4GZ66\",\n",
      "                \"excange\": \"italy\",\n",
      "                \"percent\": 0.0,\n",
      "                \"last_price\": 27.815\n",
      "            },\n",
      "            {\n",
      "                \"ticker\": \"EMH5\",\n",
      "                \"isin\": \"IE00BP46NG52\",\n",
      "                \"excange\": \"italy\",\n",
      "                \"percent\": 29.96,\n",
      "                \"last_price\": 25.065\n",
      "            },\n",
      "            {\n",
      "                \"ticker\": \"GGOV\",\n",
      "                \"isin\": \"LU1437016204\",\n",
      "                \"excange\": \"france\",\n",
      "                \"percent\": 5.73,\n",
      "                \"last_price\": 47.05\n",
      "            },\n",
      "            {\n",
      "                \"ticker\": \"SWDA\",\n",
      "                \"isin\": \"IE00B4L5Y983\",\n",
      "                \"excange\": \"italy\",\n",
      "                \"percent\": 64.31,\n",
      "                \"last_price\": 69.38\n",
      "            }\n",
      "        ],\n",
      "        \"risk\": 0.12093677966257205,\n",
      "        \"expected_return\": 0.08641993052770258,\n",
      "        \"sharpe_ratio\": 0.7063188780620281\n",
      "    }\n",
      "]\n"
     ]
    }
   ],
   "source": [
    "#pretty print\n",
    "print(json.dumps(resp, indent=4))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "server.ETFOut() argument after ** must be a mapping, not str",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[7], line 4\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[39mfor\u001b[39;00m layer \u001b[39min\u001b[39;00m resp:\n\u001b[1;32m      3\u001b[0m     \u001b[39mfor\u001b[39;00m etf \u001b[39min\u001b[39;00m layer:\n\u001b[0;32m----> 4\u001b[0m         e \u001b[39m=\u001b[39m ETFOut(\u001b[39m*\u001b[39m\u001b[39m*\u001b[39metf)\n\u001b[1;32m      5\u001b[0m         \u001b[39mprint\u001b[39m(e\u001b[39m.\u001b[39mticker, e\u001b[39m.\u001b[39mpercent, e\u001b[39m.\u001b[39mlast_price, \u001b[39m\"\u001b[39m\u001b[39m|\u001b[39m\u001b[39m\"\u001b[39m, end\u001b[39m=\u001b[39m\u001b[39m\"\u001b[39m\u001b[39m \u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[1;32m      6\u001b[0m     \u001b[39mprint\u001b[39m(layer\u001b[39m.\u001b[39mrisk, layer\u001b[39m.\u001b[39mexpected_return, layer\u001b[39m.\u001b[39msharpe_ratio)\n",
      "\u001b[0;31mTypeError\u001b[0m: server.ETFOut() argument after ** must be a mapping, not str"
     ]
    }
   ],
   "source": [
    "# pretty print\n",
    "for layer in resp:\n",
    "    for etf in layer:\n",
    "        e = ETFOut(**etf)\n",
    "        print(e.ticker, e.percent, e.last_price, \"|\", end=\" \")\n",
    "    print(layer.risk, layer.expected_return, layer.sharpe_ratio)\n",
    "    print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0]"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
