pythonhtmlcssrackrackspace

Drawing servers Rack using html/css or any python library


is there any library or template that can help me draw servers rack , based on the server's position in this rack?

example :

thank you for your help


Solution

  • I don't know what you need - image PNG/JPG, image SVG, text table, HTML table.

    But first it would need to read data and convert to list like this

    rows = [
       [1, 'empty']
       [2, 'firewall']
       [3, 'firewall']
       [4, 'firewall']
       [5, 'empty']
    
       # ... etc... 
    ]
    

    With this list it could be simpler to calculate positions for text on image, or generate text table, or generate HTML.

    You could use it with tabulate to generate text table
    which you can display in HTML in <pre></pre> or <code></code>

    +------+----------+
    |   Nr | Device   |
    +======+==========+
    |    1 | ?        |
    +------+----------+
    |    2 | firewall |
    +------+----------+
    |    3 | firewall |
    +------+----------+
    |    4 | firewall |
    +------+----------+
    |    5 | ?        |
    +------+----------+
    |    6 | ?        |
    +------+----------+
    |    7 | ?        |
    +------+----------+
    |    8 | ?        |
    +------+----------+
    |    9 | ?        |
    +------+----------+
    |   10 | NAS      |
    +------+----------+
    |   11 | NAS      |
    +------+----------+
    |   12 | NAS      |
    +------+----------+
    |   13 | NAS      |
    +------+----------+
    |   14 | NAS      |
    +------+----------+
    |   15 | NAS      |
    +------+----------+
    |   16 | servers1 |
    +------+----------+
    |   17 | servers1 |
    +------+----------+
    |   18 | ?        |
    +------+----------+
    |   19 | ?        |
    +------+----------+
    |   20 | server2  |
    +------+----------+
    |   21 | server2  |
    +------+----------+
    |   22 | server2  |
    +------+----------+
    |   23 | server2  |
    +------+----------+
    |   24 | server2  |
    +------+----------+
    |   25 | server2  |
    +------+----------+
    

    Minimal working code for text table

    text = '''servers1 - 15 - 17
    server2 - 20 - 25
    firewall - 2 - 4
    NAS - 10 - 15'''
    
    import io
    
    # --- read to dictionary ---
    
    data = {}
    counter = {}
    
    with io.StringIO(text) as fh:
        for line in fh:
            line = line.strip()
            name, start, end = line.split(' - ')
            start = int(start)
            end = int(end)
    
            # - count -
            counter[name] = end-start+1
            
            for x in range(start, end+1):
                data[x] = name
    
    # - display counter -
    #print(counter)
    for name, number in counter.items():
        print(f'{name:10}: {number}')
                
    # --- convert to list ---
    
    rows = []
    last = max(data.keys())
    
    for x in range(1, last+1):
        if x in data:
            name = data[x]
        else:
            name = '?'
        rows.append([x, name])
        
    #print(rows)
    
    # --- display table ---
    
    import tabulate
    
    print(tabulate.tabulate(rows, headers=['Nr', 'Device'], tablefmt='grid'))
    
    # - count -
    import collections
    counter = collections.Counter(data.values())
    
    # - display counter -
    #print(counter)
    for name, number in counter.items():
        print(f'{name:10}: {number}')
    

    EDIT:

    If you put rows in pandas.DataFrame then you can use .to_html() to generate it as <table></table>

    But you can use rows also to generate <table> manually

    table = "<table>\n"
    
    table += "  <tr>\n    <th>Nr</th>\n    <th>Device</th>\n  </tr>\n"
    
    for number, device in rows:
        table += f"  <tr>\n    <td>{number}</td>\n    <td>{device}</td>\n  </th>\n"
    
    table += "</table>\n"
    
    print(table)
    

    Result:

    <table>
      <tr>
        <th>Nr</th>
        <th>Device</th>
      </tr>
      <tr>
        <td>1</td>
        <td>?</td>
      </th>
      <tr>
        <td>2</td>
        <td>firewall</td>
      </th>
      <tr>
        <td>3</td>
        <td>firewall</td>
      </th>
      <tr>
        <td>4</td>
        <td>firewall</td>
      </th>
      <tr>
        <td>5</td>
        <td>?</td>
      </th>
      <tr>
        <td>6</td>
        <td>?</td>
      </th>
      <tr>
        <td>7</td>
        <td>?</td>
      </th>
      <tr>
        <td>8</td>
        <td>?</td>
      </th>
      <tr>
        <td>9</td>
        <td>?</td>
      </th>
      <tr>
        <td>10</td>
        <td>NAS</td>
      </th>
      <tr>
        <td>11</td>
        <td>NAS</td>
      </th>
      <tr>
        <td>12</td>
        <td>NAS</td>
      </th>
      <tr>
        <td>13</td>
        <td>NAS</td>
      </th>
      <tr>
        <td>14</td>
        <td>NAS</td>
      </th>
      <tr>
        <td>15</td>
        <td>NAS</td>
      </th>
      <tr>
        <td>16</td>
        <td>servers1</td>
      </th>
      <tr>
        <td>17</td>
        <td>servers1</td>
      </th>
      <tr>
        <td>18</td>
        <td>?</td>
      </th>
      <tr>
        <td>19</td>
        <td>?</td>
      </th>
      <tr>
        <td>20</td>
        <td>server2</td>
      </th>
      <tr>
        <td>21</td>
        <td>server2</td>
      </th>
      <tr>
        <td>22</td>
        <td>server2</td>
      </th>
      <tr>
        <td>23</td>
        <td>server2</td>
      </th>
      <tr>
        <td>24</td>
        <td>server2</td>
      </th>
      <tr>
        <td>25</td>
        <td>server2</td>
      </th>
    </table>
    

    EDIT:

    If you use flask then you can send rows to template

    return render_template('template.html', rows=rows)
    

    and run loop directly in template

    <table>
      <tr>
         <th>Nr</th>
         <th>Device</th>
      </tr>
    
    {% for number, device in rows %}
      <tr>
         <td>{{ number }}</td>
         <td>{{ device }}</td>
      </tr>
    {% endfor %}  
    
    </table>