stop flask duplicating a loaded variable












1














I'm building a basic cloud infrastructure management site and have a problem with the page that lists virtual machines.



The flask app pulls a list that is generated via various cloud platform's APIs, and is in the below format:



vm_list = {
'vmid': ,
'name': ,
'state': ,
'platform':
}


the list is populated by looping through the API output and appending each value like so:



def zip_list():
...
for node in driver.list_nodes():
vm_list["vmid"].append(node.uuid)
vm_list["name"].append(node.name)
vm_list["state"].append(node.state)
vm_list["platform"].append(driver.name)
...
myVms = zip(vm_list['name'], vm_list['vmid'], vm_list['platform'], vm_list['state'])
return myVms


I'm loading this via my flask app like this:



@app.route('/vms/')
def vms():
myVms = {}
myVms = vm.zip_list()
return render_template('VMs.html', vm_list=myVms)


The VMs.html page loads this data into a table:



<table class="tableClass">
<tr>
<th>Name</th>
<th>id</th>
<th>Plaform</th>
<th>State</th>
</tr>
{% for row in vm_list %}
<tr>
<td>{{ row[0] }}</td>
<td>{{ row[1] }}</td>
<td>{{ row[2] }}</td>
<td>{{ row[3] }}</td>
<tr>
{% endfor %}
</table>


And this works fine, loading the data as expected. However my problem is each time I refresh the page, the data is loaded and appended to the list once again, doubling the table size. Each refresh adds the whole vm_list list to the table once more.



I had thought this may be resolved by "nulling" the myVms variable each time it's called (i.e. myVms = {}) in the flask app script and/or the zip_list function but that doesn't seem to work; the issue still persists.



I also looked into flask-caching to see if clearing flask's cache each reload would fix it but it appears not to.



I'm thinking that I can change something in the html file to force this to only load once per session or something similar, but my front-end skills don't reach out that far.



Does anyone have any idea what I can do in this situation or where I'm going wrong? Any advice is greatly appreciated.










share|improve this question



























    1














    I'm building a basic cloud infrastructure management site and have a problem with the page that lists virtual machines.



    The flask app pulls a list that is generated via various cloud platform's APIs, and is in the below format:



    vm_list = {
    'vmid': ,
    'name': ,
    'state': ,
    'platform':
    }


    the list is populated by looping through the API output and appending each value like so:



    def zip_list():
    ...
    for node in driver.list_nodes():
    vm_list["vmid"].append(node.uuid)
    vm_list["name"].append(node.name)
    vm_list["state"].append(node.state)
    vm_list["platform"].append(driver.name)
    ...
    myVms = zip(vm_list['name'], vm_list['vmid'], vm_list['platform'], vm_list['state'])
    return myVms


    I'm loading this via my flask app like this:



    @app.route('/vms/')
    def vms():
    myVms = {}
    myVms = vm.zip_list()
    return render_template('VMs.html', vm_list=myVms)


    The VMs.html page loads this data into a table:



    <table class="tableClass">
    <tr>
    <th>Name</th>
    <th>id</th>
    <th>Plaform</th>
    <th>State</th>
    </tr>
    {% for row in vm_list %}
    <tr>
    <td>{{ row[0] }}</td>
    <td>{{ row[1] }}</td>
    <td>{{ row[2] }}</td>
    <td>{{ row[3] }}</td>
    <tr>
    {% endfor %}
    </table>


    And this works fine, loading the data as expected. However my problem is each time I refresh the page, the data is loaded and appended to the list once again, doubling the table size. Each refresh adds the whole vm_list list to the table once more.



    I had thought this may be resolved by "nulling" the myVms variable each time it's called (i.e. myVms = {}) in the flask app script and/or the zip_list function but that doesn't seem to work; the issue still persists.



    I also looked into flask-caching to see if clearing flask's cache each reload would fix it but it appears not to.



    I'm thinking that I can change something in the html file to force this to only load once per session or something similar, but my front-end skills don't reach out that far.



    Does anyone have any idea what I can do in this situation or where I'm going wrong? Any advice is greatly appreciated.










    share|improve this question

























      1












      1








      1


      2





      I'm building a basic cloud infrastructure management site and have a problem with the page that lists virtual machines.



      The flask app pulls a list that is generated via various cloud platform's APIs, and is in the below format:



      vm_list = {
      'vmid': ,
      'name': ,
      'state': ,
      'platform':
      }


      the list is populated by looping through the API output and appending each value like so:



      def zip_list():
      ...
      for node in driver.list_nodes():
      vm_list["vmid"].append(node.uuid)
      vm_list["name"].append(node.name)
      vm_list["state"].append(node.state)
      vm_list["platform"].append(driver.name)
      ...
      myVms = zip(vm_list['name'], vm_list['vmid'], vm_list['platform'], vm_list['state'])
      return myVms


      I'm loading this via my flask app like this:



      @app.route('/vms/')
      def vms():
      myVms = {}
      myVms = vm.zip_list()
      return render_template('VMs.html', vm_list=myVms)


      The VMs.html page loads this data into a table:



      <table class="tableClass">
      <tr>
      <th>Name</th>
      <th>id</th>
      <th>Plaform</th>
      <th>State</th>
      </tr>
      {% for row in vm_list %}
      <tr>
      <td>{{ row[0] }}</td>
      <td>{{ row[1] }}</td>
      <td>{{ row[2] }}</td>
      <td>{{ row[3] }}</td>
      <tr>
      {% endfor %}
      </table>


      And this works fine, loading the data as expected. However my problem is each time I refresh the page, the data is loaded and appended to the list once again, doubling the table size. Each refresh adds the whole vm_list list to the table once more.



      I had thought this may be resolved by "nulling" the myVms variable each time it's called (i.e. myVms = {}) in the flask app script and/or the zip_list function but that doesn't seem to work; the issue still persists.



      I also looked into flask-caching to see if clearing flask's cache each reload would fix it but it appears not to.



      I'm thinking that I can change something in the html file to force this to only load once per session or something similar, but my front-end skills don't reach out that far.



      Does anyone have any idea what I can do in this situation or where I'm going wrong? Any advice is greatly appreciated.










      share|improve this question













      I'm building a basic cloud infrastructure management site and have a problem with the page that lists virtual machines.



      The flask app pulls a list that is generated via various cloud platform's APIs, and is in the below format:



      vm_list = {
      'vmid': ,
      'name': ,
      'state': ,
      'platform':
      }


      the list is populated by looping through the API output and appending each value like so:



      def zip_list():
      ...
      for node in driver.list_nodes():
      vm_list["vmid"].append(node.uuid)
      vm_list["name"].append(node.name)
      vm_list["state"].append(node.state)
      vm_list["platform"].append(driver.name)
      ...
      myVms = zip(vm_list['name'], vm_list['vmid'], vm_list['platform'], vm_list['state'])
      return myVms


      I'm loading this via my flask app like this:



      @app.route('/vms/')
      def vms():
      myVms = {}
      myVms = vm.zip_list()
      return render_template('VMs.html', vm_list=myVms)


      The VMs.html page loads this data into a table:



      <table class="tableClass">
      <tr>
      <th>Name</th>
      <th>id</th>
      <th>Plaform</th>
      <th>State</th>
      </tr>
      {% for row in vm_list %}
      <tr>
      <td>{{ row[0] }}</td>
      <td>{{ row[1] }}</td>
      <td>{{ row[2] }}</td>
      <td>{{ row[3] }}</td>
      <tr>
      {% endfor %}
      </table>


      And this works fine, loading the data as expected. However my problem is each time I refresh the page, the data is loaded and appended to the list once again, doubling the table size. Each refresh adds the whole vm_list list to the table once more.



      I had thought this may be resolved by "nulling" the myVms variable each time it's called (i.e. myVms = {}) in the flask app script and/or the zip_list function but that doesn't seem to work; the issue still persists.



      I also looked into flask-caching to see if clearing flask's cache each reload would fix it but it appears not to.



      I'm thinking that I can change something in the html file to force this to only load once per session or something similar, but my front-end skills don't reach out that far.



      Does anyone have any idea what I can do in this situation or where I'm going wrong? Any advice is greatly appreciated.







      python html variables flask libcloud






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 12 '18 at 14:25









      RobotJohnny

      657




      657
























          2 Answers
          2






          active

          oldest

          votes


















          1














          You are close - the variable you actually need to reset each time is not myVms but vm_list, as follows:



          class Node:
          counter = 0

          def __init__(self):
          c_str = str(Node.counter)
          self.uuid = "asdf" + c_str
          self.name = "test " + c_str
          self.state = "wow " + c_str + " such state"
          Node.counter += 1


          class Driver:
          def __init__(self, number_of_nodes):
          self.nodes =
          for x in range(number_of_nodes):
          self.nodes.append(Node())
          self.name = "the greatest driver"

          def list_nodes(self) -> list:
          return self.nodes


          driver = Driver(10)


          def zip_list():
          vm_list = {'vmid': , 'name': , 'state': , 'platform': }
          for node in driver.list_nodes():
          vm_list["vmid"].append(node.uuid)
          vm_list["name"].append(node.name)
          vm_list["state"].append(node.state)
          vm_list["platform"].append(driver.name)

          myVms = zip(vm_list['name'], vm_list['vmid'], vm_list['platform'], vm_list['state'])
          return myVms


          print("First time:")

          my_list = zip_list()
          for i in my_list:
          print(i)

          print("Second time:")

          my_list = zip_list()
          for i in my_list:
          print(i)


          If you initialise vm_list outside of the zip_list() function instead, you will see the doubling up that you are experiencing.






          share|improve this answer





















          • perfect, thank you very much! I knew I was doing something silly.. my python is a little rusty.
            – RobotJohnny
            Nov 12 '18 at 15:09



















          1














          You need to initialise vm_list with an empty dict. And if a key exists, then append to its list, else set the dict[key] with an empty list. This is done by setdefault.



          Try this:



          def zip_list():
          ...
          vm_list = {}
          for node in driver.list_nodes():
          vm_list.setdefault('vmid', ).append(node.uuid)
          vm_list.setdefault('name', ).append(node.name)
          vm_list.setdefault('state', ).append(node.state)
          vm_list.setdefault('platform', ).append(node.platform)
          ...
          myVms = zip(vm_list['name'], vm_list['vmid'], vm_list['platform'], vm_list['state'])
          return myVms





          share|improve this answer























          • nice alternative, thank you very much!
            – RobotJohnny
            Nov 12 '18 at 15:09











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53264211%2fstop-flask-duplicating-a-loaded-variable%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          You are close - the variable you actually need to reset each time is not myVms but vm_list, as follows:



          class Node:
          counter = 0

          def __init__(self):
          c_str = str(Node.counter)
          self.uuid = "asdf" + c_str
          self.name = "test " + c_str
          self.state = "wow " + c_str + " such state"
          Node.counter += 1


          class Driver:
          def __init__(self, number_of_nodes):
          self.nodes =
          for x in range(number_of_nodes):
          self.nodes.append(Node())
          self.name = "the greatest driver"

          def list_nodes(self) -> list:
          return self.nodes


          driver = Driver(10)


          def zip_list():
          vm_list = {'vmid': , 'name': , 'state': , 'platform': }
          for node in driver.list_nodes():
          vm_list["vmid"].append(node.uuid)
          vm_list["name"].append(node.name)
          vm_list["state"].append(node.state)
          vm_list["platform"].append(driver.name)

          myVms = zip(vm_list['name'], vm_list['vmid'], vm_list['platform'], vm_list['state'])
          return myVms


          print("First time:")

          my_list = zip_list()
          for i in my_list:
          print(i)

          print("Second time:")

          my_list = zip_list()
          for i in my_list:
          print(i)


          If you initialise vm_list outside of the zip_list() function instead, you will see the doubling up that you are experiencing.






          share|improve this answer





















          • perfect, thank you very much! I knew I was doing something silly.. my python is a little rusty.
            – RobotJohnny
            Nov 12 '18 at 15:09
















          1














          You are close - the variable you actually need to reset each time is not myVms but vm_list, as follows:



          class Node:
          counter = 0

          def __init__(self):
          c_str = str(Node.counter)
          self.uuid = "asdf" + c_str
          self.name = "test " + c_str
          self.state = "wow " + c_str + " such state"
          Node.counter += 1


          class Driver:
          def __init__(self, number_of_nodes):
          self.nodes =
          for x in range(number_of_nodes):
          self.nodes.append(Node())
          self.name = "the greatest driver"

          def list_nodes(self) -> list:
          return self.nodes


          driver = Driver(10)


          def zip_list():
          vm_list = {'vmid': , 'name': , 'state': , 'platform': }
          for node in driver.list_nodes():
          vm_list["vmid"].append(node.uuid)
          vm_list["name"].append(node.name)
          vm_list["state"].append(node.state)
          vm_list["platform"].append(driver.name)

          myVms = zip(vm_list['name'], vm_list['vmid'], vm_list['platform'], vm_list['state'])
          return myVms


          print("First time:")

          my_list = zip_list()
          for i in my_list:
          print(i)

          print("Second time:")

          my_list = zip_list()
          for i in my_list:
          print(i)


          If you initialise vm_list outside of the zip_list() function instead, you will see the doubling up that you are experiencing.






          share|improve this answer





















          • perfect, thank you very much! I knew I was doing something silly.. my python is a little rusty.
            – RobotJohnny
            Nov 12 '18 at 15:09














          1












          1








          1






          You are close - the variable you actually need to reset each time is not myVms but vm_list, as follows:



          class Node:
          counter = 0

          def __init__(self):
          c_str = str(Node.counter)
          self.uuid = "asdf" + c_str
          self.name = "test " + c_str
          self.state = "wow " + c_str + " such state"
          Node.counter += 1


          class Driver:
          def __init__(self, number_of_nodes):
          self.nodes =
          for x in range(number_of_nodes):
          self.nodes.append(Node())
          self.name = "the greatest driver"

          def list_nodes(self) -> list:
          return self.nodes


          driver = Driver(10)


          def zip_list():
          vm_list = {'vmid': , 'name': , 'state': , 'platform': }
          for node in driver.list_nodes():
          vm_list["vmid"].append(node.uuid)
          vm_list["name"].append(node.name)
          vm_list["state"].append(node.state)
          vm_list["platform"].append(driver.name)

          myVms = zip(vm_list['name'], vm_list['vmid'], vm_list['platform'], vm_list['state'])
          return myVms


          print("First time:")

          my_list = zip_list()
          for i in my_list:
          print(i)

          print("Second time:")

          my_list = zip_list()
          for i in my_list:
          print(i)


          If you initialise vm_list outside of the zip_list() function instead, you will see the doubling up that you are experiencing.






          share|improve this answer












          You are close - the variable you actually need to reset each time is not myVms but vm_list, as follows:



          class Node:
          counter = 0

          def __init__(self):
          c_str = str(Node.counter)
          self.uuid = "asdf" + c_str
          self.name = "test " + c_str
          self.state = "wow " + c_str + " such state"
          Node.counter += 1


          class Driver:
          def __init__(self, number_of_nodes):
          self.nodes =
          for x in range(number_of_nodes):
          self.nodes.append(Node())
          self.name = "the greatest driver"

          def list_nodes(self) -> list:
          return self.nodes


          driver = Driver(10)


          def zip_list():
          vm_list = {'vmid': , 'name': , 'state': , 'platform': }
          for node in driver.list_nodes():
          vm_list["vmid"].append(node.uuid)
          vm_list["name"].append(node.name)
          vm_list["state"].append(node.state)
          vm_list["platform"].append(driver.name)

          myVms = zip(vm_list['name'], vm_list['vmid'], vm_list['platform'], vm_list['state'])
          return myVms


          print("First time:")

          my_list = zip_list()
          for i in my_list:
          print(i)

          print("Second time:")

          my_list = zip_list()
          for i in my_list:
          print(i)


          If you initialise vm_list outside of the zip_list() function instead, you will see the doubling up that you are experiencing.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 12 '18 at 14:50









          Rob Bricheno

          2,325218




          2,325218












          • perfect, thank you very much! I knew I was doing something silly.. my python is a little rusty.
            – RobotJohnny
            Nov 12 '18 at 15:09


















          • perfect, thank you very much! I knew I was doing something silly.. my python is a little rusty.
            – RobotJohnny
            Nov 12 '18 at 15:09
















          perfect, thank you very much! I knew I was doing something silly.. my python is a little rusty.
          – RobotJohnny
          Nov 12 '18 at 15:09




          perfect, thank you very much! I knew I was doing something silly.. my python is a little rusty.
          – RobotJohnny
          Nov 12 '18 at 15:09













          1














          You need to initialise vm_list with an empty dict. And if a key exists, then append to its list, else set the dict[key] with an empty list. This is done by setdefault.



          Try this:



          def zip_list():
          ...
          vm_list = {}
          for node in driver.list_nodes():
          vm_list.setdefault('vmid', ).append(node.uuid)
          vm_list.setdefault('name', ).append(node.name)
          vm_list.setdefault('state', ).append(node.state)
          vm_list.setdefault('platform', ).append(node.platform)
          ...
          myVms = zip(vm_list['name'], vm_list['vmid'], vm_list['platform'], vm_list['state'])
          return myVms





          share|improve this answer























          • nice alternative, thank you very much!
            – RobotJohnny
            Nov 12 '18 at 15:09
















          1














          You need to initialise vm_list with an empty dict. And if a key exists, then append to its list, else set the dict[key] with an empty list. This is done by setdefault.



          Try this:



          def zip_list():
          ...
          vm_list = {}
          for node in driver.list_nodes():
          vm_list.setdefault('vmid', ).append(node.uuid)
          vm_list.setdefault('name', ).append(node.name)
          vm_list.setdefault('state', ).append(node.state)
          vm_list.setdefault('platform', ).append(node.platform)
          ...
          myVms = zip(vm_list['name'], vm_list['vmid'], vm_list['platform'], vm_list['state'])
          return myVms





          share|improve this answer























          • nice alternative, thank you very much!
            – RobotJohnny
            Nov 12 '18 at 15:09














          1












          1








          1






          You need to initialise vm_list with an empty dict. And if a key exists, then append to its list, else set the dict[key] with an empty list. This is done by setdefault.



          Try this:



          def zip_list():
          ...
          vm_list = {}
          for node in driver.list_nodes():
          vm_list.setdefault('vmid', ).append(node.uuid)
          vm_list.setdefault('name', ).append(node.name)
          vm_list.setdefault('state', ).append(node.state)
          vm_list.setdefault('platform', ).append(node.platform)
          ...
          myVms = zip(vm_list['name'], vm_list['vmid'], vm_list['platform'], vm_list['state'])
          return myVms





          share|improve this answer














          You need to initialise vm_list with an empty dict. And if a key exists, then append to its list, else set the dict[key] with an empty list. This is done by setdefault.



          Try this:



          def zip_list():
          ...
          vm_list = {}
          for node in driver.list_nodes():
          vm_list.setdefault('vmid', ).append(node.uuid)
          vm_list.setdefault('name', ).append(node.name)
          vm_list.setdefault('state', ).append(node.state)
          vm_list.setdefault('platform', ).append(node.platform)
          ...
          myVms = zip(vm_list['name'], vm_list['vmid'], vm_list['platform'], vm_list['state'])
          return myVms






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 12 '18 at 14:59

























          answered Nov 12 '18 at 14:53









          jerrymouse

          8,470104867




          8,470104867












          • nice alternative, thank you very much!
            – RobotJohnny
            Nov 12 '18 at 15:09


















          • nice alternative, thank you very much!
            – RobotJohnny
            Nov 12 '18 at 15:09
















          nice alternative, thank you very much!
          – RobotJohnny
          Nov 12 '18 at 15:09




          nice alternative, thank you very much!
          – RobotJohnny
          Nov 12 '18 at 15:09


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53264211%2fstop-flask-duplicating-a-loaded-variable%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          The Sandy Post

          Danny Elfman

          Pages that link to "Head v. Amoskeag Manufacturing Co."