{"id":22222179,"url":"https://github.com/davewalker5/networkcalculator","last_synced_at":"2025-10-08T02:06:15.855Z","repository":{"id":181166114,"uuid":"666333778","full_name":"davewalker5/NetworkCalculator","owner":"davewalker5","description":"Python application to calculate network details and perform subnetting","archived":false,"fork":false,"pushed_at":"2025-08-10T08:43:05.000Z","size":79,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-08T02:03:33.295Z","etag":null,"topics":["api-client","api-rest","network","networking","python","python3","subnet","subnet-calculator","subnetting"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/davewalker5.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-07-14T08:57:06.000Z","updated_at":"2025-08-10T08:43:06.000Z","dependencies_parsed_at":null,"dependency_job_id":"9ff50ee9-2c34-47ae-af45-5723dd352178","html_url":"https://github.com/davewalker5/NetworkCalculator","commit_stats":null,"previous_names":["davewalker5/networkcalculator"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/davewalker5/NetworkCalculator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davewalker5%2FNetworkCalculator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davewalker5%2FNetworkCalculator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davewalker5%2FNetworkCalculator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davewalker5%2FNetworkCalculator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/davewalker5","download_url":"https://codeload.github.com/davewalker5/NetworkCalculator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davewalker5%2FNetworkCalculator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278877092,"owners_count":26061381,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-client","api-rest","network","networking","python","python3","subnet","subnet-calculator","subnetting"],"created_at":"2024-12-02T23:17:26.910Z","updated_at":"2025-10-08T02:06:15.838Z","avatar_url":"https://github.com/davewalker5.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":".. image:: https://github.com/davewalker5/NetworkCalculator/workflows/Python%20CI%20Build/badge.svg\r\n    :target: https://github.com/davewalker5/NetworkCalculator/actions\r\n    :alt: Build Status\r\n\r\n.. image:: https://codecov.io/gh/davewalker5/NetworkCalculator/branch/main/graph/badge.svg?token=1E72RZU3CQ\r\n    :target: https://codecov.io/gh/davewalker5/NetworkCalculator\r\n    :alt: Coverage\r\n\r\n.. image:: https://img.shields.io/github/issues/davewalker5/NetworkCalculator\r\n    :target: https://github.com/davewalker5/NetworkCalculator/issues\r\n    :alt: GitHub issues\r\n\r\n.. image:: https://img.shields.io/github/v/release/davewalker5/NetworkCalculator.svg?include_prereleases\r\n    :target: https://github.com/davewalker5/NetworkCalculator/releases\r\n    :alt: Releases\r\n\r\n.. image:: https://img.shields.io/badge/License-mit-blue.svg\r\n    :target: https://github.com/davewalker5/NetworkCalculator/blob/main/LICENSE\r\n    :alt: License\r\n\r\n.. image:: https://img.shields.io/badge/language-python-blue.svg\r\n    :target: https://www.python.org\r\n    :alt: Language\r\n\r\n.. image:: https://img.shields.io/github/languages/code-size/davewalker5/NetworkCalculator\r\n    :target: https://github.com/davewalker5/NetworkCalculator/\r\n    :alt: GitHub code size in bytes\r\n\r\n\r\nNetwork Calculator\r\n==================\r\n\r\nThe Network Calculator is an application written in Python for calculating network properties and calculating subnets. It has\r\nthe following components:\r\n\r\n- A Flask-based REST API for performing the calculations\r\n- A simple client for applications calling the REST API\r\n- A simple command-line application that uses the API to perofm\r\n\r\n\r\nStructure\r\n=========\r\n\r\n+-------------------------------+----------------------------------------------------------------------+\r\n| **Package**                   | **Contents**                                                         |\r\n+-------------------------------+----------------------------------------------------------------------+\r\n| api                           | Flask-based REST API                                                 |\r\n+-------------------------------+----------------------------------------------------------------------+\r\n| cli                           | Command-line client (requires a running API)                         |\r\n+-------------------------------+----------------------------------------------------------------------+\r\n| client                        | Simple client wrapper to allow applications to call the API          |\r\n+-------------------------------+----------------------------------------------------------------------+\r\n| common                        | Common code used by the network calculation functions                |\r\n+-------------------------------+----------------------------------------------------------------------+\r\n| ipv4                          | IPv4 network details and subnetting implementation                   |\r\n+-------------------------------+----------------------------------------------------------------------+\r\n| logging_wrapper               | Logging wrapper used by the API to write application logs            |\r\n+-------------------------------+----------------------------------------------------------------------+\r\n\r\n\r\nREST API Endpoints\r\n==================\r\n\r\n/ipv4/network\r\n-------------\r\n\r\nReturns the following details for the network specified in the request body:\r\n\r\n- Network address\r\n- Subnet mask\r\n- Broadcast address\r\n- First host IP address\r\n- Last host IP address\r\n\r\nThe request body is in text/json format can be supplied in one of two forms, depending on the format in which the IP address is specified:\r\n\r\n::\r\n\r\n    {\r\n        \"ip_address\": \"172.16.35.123\",\r\n        \"subnet_mask\": \"255.255.240.0\"\r\n    }\r\n\r\nor:\r\n\r\n::\r\n\r\n    {\r\n        \"ip_address\": \"172.16.35.123/20\"\r\n    }\r\n\r\nRequests are sent using the POST verb.\r\n\r\nA typical response is:\r\n\r\n::\r\n\r\n    [\r\n        {\r\n            \"broadcast\": [172, 16, 47, 255],\r\n            \"broadcast_binary\": [\"10101100\", \"00010000\", \"00101111\", \"11111111\"],\r\n            \"first\": [172, 16, 32, 1],\r\n            \"first_binary\": [\"10101100\", \"00010000\", \"00100000\", \"00000001\"],\r\n            \"last\": [172, 16, 47, 254],\r\n            \"last_binary\": [\"10101100\", \"00010000\", \"00101111\", \"11111110\"],\r\n            \"network\": [172, 16, 32, 0],\r\n            \"network_binary\": [\"10101100\", \"00010000\", \"00100000\", \"00000000\"],\r\n            \"network_bits\": 20,\r\n            \"subnet\": [255, 255, 240, 0],\r\n            \"subnet_binary\": [\"11111111\", \"11111111\", \"11110000\", \"00000000\"]\r\n        }\r\n    ]\r\n\r\n\r\n/ipv4/subnet\r\n------------\r\n\r\nGiven an IP address and a subnet mask (or number of network bits) and a number of hosts or networks, calculate the subnet details for subnetting the supplied IP into one of:\r\n\r\n- A set of subnets each of which can support a specified number of hosts\r\n- A specified number of subnets, each supporting as many hosts as possible\r\n- A set of subnets with a specified number of network bits, each supporting as many hosts as possible\r\n\r\nSubnets Supporting a Specified Number of Hosts\r\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n\r\nThe request body is in text/json format and can be supplied in several forms, depending on the format in which the IP address is specified:\r\n\r\n::\r\n\r\n    {\r\n        \"ip_address\": \"10.1.1.0\",\r\n        \"subnet_mask\": \"255.255.255.0\",\r\n        \"hosts\": 14\r\n    }\r\n\r\nor:\r\n\r\n::\r\n\r\n    {\r\n        \"ip_address\": \"10.1.1.0/24\",\r\n        \"hosts\": 14\r\n    }\r\n\r\nRequests are sent using the POST verb.\r\n\r\nSubnet Into a Specified Number of Networks\r\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n\r\nThe request body is in text/json format and can be supplied in several forms, depending on the format in which the IP address is specified:\r\n\r\n::\r\n\r\n    {\r\n        \"ip_address\": \"10.128.192.0\",\r\n        \"subnet_mask\": \"255.255.192.0\",\r\n        \"networks\": 30\r\n    }\r\n\r\nor:\r\n\r\n::\r\n\r\n    {\r\n        \"ip_address\": \"10.128.192.0/18\",\r\n        \"networks\": 30\r\n    }\r\n\r\nRequests are sent using the POST verb.\r\n\r\nSubnet Based on a Number of Network Bits\r\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n\r\nThe request body is in text/json format and can be supplied in several forms, depending on the format in which the IP address is specified:\r\n\r\n::\r\n\r\n    {\r\n        \"ip_address\": \"192.168.1.96\",\r\n        \"subnet_mask\": \"255.255.255.240\",\r\n        \"network_bits\": 30\r\n    }\r\n\r\nor:\r\n\r\n::\r\n\r\n    {\r\n        \"ip_address\": \"192.168.1.96/28\",\r\n        \"network_bits\": 30\r\n    }\r\n\r\nRequests are sent using the POST verb.\r\n\r\nResponse\r\n--------\r\n\r\nA typical response is as follows:\r\n\r\n::\r\n\r\n    [\r\n        {\r\n            \"network_bits\": 23,\r\n            \"networks\": [\r\n                {\r\n                    \"broadcast\": [10, 128, 193, 255],\r\n                    \"broadcast_binary\": [\"00001010\", \"10000000\", \"11000001\", \"11111111\"],\r\n                    \"first\": [10, 128, 192, 1],\r\n                    \"first_binary\": [\"00001010\", \"10000000\", \"11000000\", \"00000001\"],\r\n                    \"last\": [10, 128, 193, 254],\r\n                    \"last_binary\": [\"00001010\", \"10000000\", \"11000001\", \"11111110\"],\r\n                    \"network\": [10, 128, 192, 0],\r\n                    \"network_binary\": [\"00001010\", \"10000000\", \"11000000\", \"00000000\"]\r\n                },\r\n                :\r\n                :\r\n            ]\r\n        }\r\n    ]\r\n\r\nThe \"networks\" element of the response is a list of network details for each of the calculated subnets.\r\n\r\n\r\n/ipv4/samesubnet\r\n----------------\r\n\r\nDetermines whether or not two IP addresses are on the same subnet. The request body is in text/json format and can be supplied in several forms, depending on the format in which the IP address is specified:\r\n\r\n::\r\n\r\n    {\r\n        \"ip_address_1\": \"10.1.255.1\",\r\n        \"ip_address_2\": \"10.1.128.2\",\r\n        \"subnet_mask\": \"255.255.128.0\"\r\n    }\r\n\r\nor:\r\n\r\n::\r\n\r\n    {\r\n        \"ip_address_1\": \"10.1.255.1/17\",\r\n        \"ip_address_2\": \"10.1.128.2/17\"\r\n    }\r\n\r\nRequests are sent using the POST verb.\r\n\r\nA typical response is as follows:\r\n\r\n::\r\n\r\n    {\r\n        \"same_subnet\": true\r\n    }\r\n\r\n\r\nRunning the Application\r\n=======================\r\n\r\nPre-requisites\r\n--------------\r\n\r\nTo run the application, a virtual environment should be created, the requirements should be installed using pip and the\r\nenvironment should be activated.\r\n\r\n\r\nRunning the REST API and CLI\r\n----------------------------\r\n\r\nTo run the REST API in the Flask development web server, enter the following from the root of the project:\r\n\r\n::\r\n\r\n    export PYTHONPATH=`pwd`/src\r\n    export FLASK_DEBUG=1\r\n    python -m api\r\n\r\nThe first two commands will need to be modified based on the current operating system. Once the development server\r\nis running, use the following commands in another terminal window to run the CLI:\r\n\r\n::\r\n\r\n    export PYTHONPATH=`pwd`/src\r\n    python -m cli http://127.0.0.1 5000\r\n\r\nThe arguments are the host name and protocol for the API and the port number it's listening on, which default to the values shown.\r\n\r\nOnce the CLI is running, the following should be displayed:\r\n\r\n::\r\n\r\n    API Host: http://127.0.0.1\r\n    API Port: 5000\r\n\r\n    1: Calculate Network Details\r\n    2: Subnetting\r\n    3: Same Subnet\r\n\r\n    Which calculation do you want to do?\r\n\r\nAs an example, enter 2 and, when prompted, enter the following values:\r\n\r\n+--------------------+-------------+\r\n| Property           | Value       |\r\n+--------------------+-------------+\r\n| IP Address         | 10.1.1.0/24 |\r\n+--------------------+-------------+\r\n| Subnet Mask        | Blank       |\r\n+--------------------+-------------+\r\n| Number of Hosts    | 14          |\r\n+--------------------+-------------+\r\n| Number of Networks | 0           |\r\n+--------------------+-------------+\r\n\r\nIn this example:\r\n\r\n- The subnet mask isn't needed because the IP address has the /24 suffix, that specifies the length of the network prefix\r\n- The number of networks is entered as 0 because we're subnetting for a number of hosts per network, not a number of networks\r\n\r\nThe following should be the output:\r\n\r\n::\r\n\r\n    Subnet Mask       : 255.255.255.240\r\n    Network Bits      : 28\r\n\r\n    #  Network            First Host         Last Host          Broadcast\r\n    -  -------            ----------         ---------          ---------\r\n    1  10.1.1.0           10.1.1.1           10.1.1.14          10.1.1.15\r\n    2  10.1.1.16          10.1.1.17          10.1.1.30          10.1.1.31\r\n    3  10.1.1.32          10.1.1.33          10.1.1.46          10.1.1.47\r\n    4  10.1.1.48          10.1.1.49          10.1.1.62          10.1.1.63\r\n    5  10.1.1.64          10.1.1.65          10.1.1.78          10.1.1.79\r\n    6  10.1.1.80          10.1.1.81          10.1.1.94          10.1.1.95\r\n    7  10.1.1.96          10.1.1.97          10.1.1.110         10.1.1.111\r\n    8  10.1.1.112         10.1.1.113         10.1.1.126         10.1.1.127\r\n    9  10.1.1.128         10.1.1.129         10.1.1.142         10.1.1.143\r\n    10 10.1.1.144         10.1.1.145         10.1.1.158         10.1.1.159\r\n    11 10.1.1.160         10.1.1.161         10.1.1.174         10.1.1.175\r\n    12 10.1.1.176         10.1.1.177         10.1.1.190         10.1.1.191\r\n    13 10.1.1.192         10.1.1.193         10.1.1.206         10.1.1.207\r\n    14 10.1.1.208         10.1.1.209         10.1.1.222         10.1.1.223\r\n    15 10.1.1.224         10.1.1.225         10.1.1.238         10.1.1.239\r\n    16 10.1.1.240         10.1.1.241         10.1.1.254         10.1.1.255\r\n\r\n\r\nThe application will then prompt for the next subnet to calculate. Hit ENTER to return to the main menu and ENTER again to quit.\r\n\r\nUnit Tests and Coverage\r\n=======================\r\n\r\nCurrently, the unit tests use a SQLite database as the back-end rather than mocking the database.\r\n\r\nTo run the unit tests, a virtual environment should be created, the requirements should be installed using pip and the\r\nenvironment should be activated.\r\n\r\nThe tests can then be run from the command line, at the root of the project folder, as follows:\r\n\r\n::\r\n\r\n    export PYTHONPATH=`pwd`/src/\r\n    python -m pytest\r\n\r\nThe first command adds the source folder, containing the two packages under test, to the PYTHONPATH environment\r\nvariable so the packages will be found when the tests attempt to import them. The command will need to be modified\r\nbased on the current operating system.\r\n\r\nSimilarly, a coverage report can be generated by running the following commands from the root of the project folder:\r\n\r\n::\r\n\r\n    export PYTHONPATH=`pwd`/src/\r\n    python -m pytest --cov=src --cov-branch --cov-report html\r\n\r\nThis will create a folder \"htmlcov\" containing the coverage report in HTML format.\r\n\r\n\r\nDependencies\r\n============\r\n\r\nThe application has dependencies listed in requirements.txt.\r\n\r\n\r\nLicense\r\n=======\r\n\r\nThis software is licensed under the MIT License:\r\n\r\nhttps://opensource.org/licenses/MIT\r\n\r\nCopyright 2023 David Walker\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated\r\ndocumentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the\r\nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit\r\npersons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the\r\nSoftware.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\r\nWARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\r\nOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavewalker5%2Fnetworkcalculator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavewalker5%2Fnetworkcalculator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavewalker5%2Fnetworkcalculator/lists"}