{"id":13710863,"url":"https://github.com/timeforplanb123/anac","last_synced_at":"2025-05-06T20:30:59.796Z","repository":{"id":37016820,"uuid":"461777862","full_name":"timeforplanb123/anac","owner":"timeforplanb123","description":"Async NetBox API Client","archived":false,"fork":false,"pushed_at":"2022-06-19T07:06:54.000Z","size":555,"stargazers_count":14,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-27T21:47:10.762Z","etag":null,"topics":["netbox","netbox-api"],"latest_commit_sha":null,"homepage":"https://timeforplanb123.github.io/anac","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/timeforplanb123.png","metadata":{"files":{"readme":"README.md","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}},"created_at":"2022-02-21T08:54:09.000Z","updated_at":"2024-12-16T12:25:02.000Z","dependencies_parsed_at":"2022-08-18T22:00:45.592Z","dependency_job_id":null,"html_url":"https://github.com/timeforplanb123/anac","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timeforplanb123%2Fanac","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timeforplanb123%2Fanac/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timeforplanb123%2Fanac/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timeforplanb123%2Fanac/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timeforplanb123","download_url":"https://codeload.github.com/timeforplanb123/anac/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252764181,"owners_count":21800651,"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","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":["netbox","netbox-api"],"created_at":"2024-08-02T23:01:01.558Z","updated_at":"2025-05-06T20:30:59.513Z","avatar_url":"https://github.com/timeforplanb123.png","language":"Python","funding_links":[],"categories":["SDKs"],"sub_categories":[],"readme":"[![Code style: black](https://img.shields.io/badge/code%20style-black-black?style=for-the-badge)](https://github.com/ambv/black)\n[![PyPI](https://img.shields.io/pypi/v/anac?style=for-the-badge\u0026logo=pypi)](https://pypi.org/project/anac)\n[![License: APACHE-2.0](https://img.shields.io/github/license/timeforplanb123/anac?style=for-the-badge)](https://opensource.org/licenses/Apache-2.0)\n[![Docs](https://img.shields.io/badge/docs-passing-green?style=for-the-badge)](https://timeforplanb123.github.io/anac/)\n[![Codecov](https://img.shields.io/codecov/c/github/timeforplanb123/anac?style=for-the-badge\u0026logo=codecov)](https://codecov.io/gh/timeforplanb123/anac)\n\n\nanac\n==========\n\nPython **A**sync **N**etBox **A**PI **C**lient, based on \u003ca href=\"https://github.com/encode/httpx\" target=\"_blank\"\u003ehttpx\u003c/a\u003e and \u003ca href=\"https://github.com/samuelcolvin/pydantic\" target=\"_blank\"\u003epydantic\u003c/a\u003e\n\n\n## Documentation\n\n\u003ca href=\"https://timeforplanb123.github.io/anac\" target=\"_blank\"\u003ehttps://timeforplanb123.github.io/anac\u003c/a\u003e\n\n\n## Features \n\n* Minimalistic interface\n* Async only\n* Python interpreter autocompletion\n* Supports \u003ca href=\"https://github.com/netbox-community/netbox\" target=\"_blank\"\u003eNetBox\u003c/a\u003e 2.x, 3.x\n* Flexibility. All the objects are coroutines or coroutine iterators\n* Simple integration with parsers (\u003ca href=\"https://github.com/google/textfsm\" target=\"_blank\"\u003eTextFSM\u003c/a\u003e, \u003ca href=\"https://github.com/dmulyalin/ttp\" target=\"_blank\"\u003eTTP\u003c/a\u003e)\n\n\n## Quick Start \n\n#### Install\n\nPlease, at first, check the dependencies in `pyproject.toml` and create new virtual environment if necessary and then:\n\n**with pip:**\n\n```text\npip install anac \n```\n\n**with git:**\n\n```text\ngit clone https://github.com/timeforplanb123/anac.git\ncd anac \npip install .\n# or\npoetry install\n```\n\n\n#### Simple Examples\n\n\n#### Api Instantiating\n```python\nfrom anac import api\n\na = api(\n    \"https://demo.netbox.dev\",\n    token=\"cf1dc7b04de5f27cfc93aba9e3f537d2ad6fdf8c\",\n)\n# get openapi spec and create attributes/endpoints   \nawait a.openapi()\n```\n#### `get` some device and `patch` it \n\n[![asciicast](https://asciinema.org/a/DmirYBxwl40VP9Delp6e0J3dE.svg)](https://asciinema.org/a/DmirYBxwl40VP9Delp6e0J3dE)\n\n```python\nIn [1]: some_device = await a.dcim_devices(get={\"name\": \"dmi01-rochster-sw01\"})\n\nIn [2]: some_device.name\nOut[2]: 'dmi01-rochster-sw01'\n\nIn [3]: some_device.device_type\nOut[3]:\n{'id': 7,\n 'url': 'https://demo.netbox.dev/api/dcim/device-types/7/',\n 'display': 'C9200-48P',\n 'manufacturer': {'id': 3,\n  'url': 'https://demo.netbox.dev/api/dcim/manufacturers/3/',\n  'display': 'Cisco',\n  'name': 'Cisco',\n  'slug': 'cisco'},\n 'model': 'C9200-48P',\n 'slug': 'c9200-48p'}\n\nIn [4]: some_device.status\nOut[4]: {'value': 'active', 'label': 'Active'}\n\nIn [5]: some_device = await some_device(patch={\"status\": \"failed\"})\n\nIn [6]: some_device.status\nOut[6]: {'value': 'failed', 'label': 'Failed'}\n```\n\n#### `get` some 2 devices and `put` + `patch` them\n```python\nIn [7]: some_devices = await a.dcim_devices(\n    ...:     get=[{\"name\": \"dmi01-rochster-sw01\"}, {\"name\": \"dmi01-rochester-rtr01\"}]\n    ...: )\n\n# EndpointAsIterator is a coroutine iterator with 2 coroutines\nIn [8]: some_devices\nOut[8]: EndpointAsIterator(api=Api, url='https://demo.netbox.dev/api', endpoint='/dcim/devices/')\n\nIn [9]: import asyncio\n\n# run 2 coroutines in the event loop\nIn [10]: some_devices = await asyncio.gather(*some_devices)\n\n# EndpointId is a NetBox '/dcim/devices/' object and coroutine\nIn [11]: some_devices\nOut[11]: \n[EndpointId(api=Api, url='https://demo.netbox.dev/api/dcim/devices/21/', endpoint='/dcim/devices/'),\n EndpointId(api=Api, url='https://demo.netbox.dev/api/dcim/devices/8/', endpoint='/dcim/devices/')]\n\nIn [12]: patch_some_devices = [coro(patch={\"status\": \"failed\"}) for coro in some_devices]\n\n# run 2 coroutines in the event loop\nIn [13]: patch_some_devices = await asyncio.gather(*patch_some_devices)\n\n# EndpointId is a coroutine, again\nIn [14]: patch_some_devices\nOut[14]: \n[EndpointId(api=Api, url='https://demo.netbox.dev/api/dcim/devices/21/', endpoint='/dcim/devices/{id}/'),\n EndpointId(api=Api, url='https://demo.netbox.dev/api/dcim/devices/8/', endpoint='/dcim/devices/{id}/')]\n\nIn [15]: patch_some_devices[0].name\nOut[15]: 'dmi01-rochster-sw01'\n\nIn [16]: patch_some_devices[0].status\nOut[16]: {'value': 'failed', 'label': 'Failed'}\n\nIn [17]: patch_some_devices[1].name\nOut[17]: 'dmi01-rochester-rtr01'\n\nIn [18]: patch_some_devices[1].status\nOut[18]: {'value': 'failed', 'label': 'Failed'}\n```\n\n#### `get` all devices\n```python\nIn [19]: all_devices = await a.dcim_devices(get={})\n# or\nIn [20]: all_devices = await a.dcim_devices()\n\n# EndpointIdIterator is an coroutine iterator with EndpointId objects\nIn [21]: all_devices\nOut[21]: EndpointIdIterator(api=Api, url='https://demo.netbox.dev/api', endpoint='/dcim/devices/')\n\nIn [22]: len(all_devices)\nOut[22]: 50\n\nIn [23]: all_devices[49]\nOut[23]: EndpointId(api=Api, url='https://demo.netbox.dev/api/dcim/devices/95/', endpoint='/dcim/devices/')\n\nIn [24]: all_devices[49].name\nOut[24]: 'ncsu118-distswitch1'\n\n# by default, 'limit' parameter = 50, but you can run 'get' request with custom 'limit'\nIn [25]: all_devices = await a.dcim_devices(get={\"limit\": 100})\n\nIn [26]: len(all_devices)\nOut[26]: 75\n\nIn [27]: all_devices[74]\nOut[27]: EndpointId(api=Api, url='https://demo.netbox.dev/api/dcim/devices/106/', endpoint='/dcim/devices/')\n\nIn [28]: all_devices[74].id\nOut[28]: 106\n```\n\n#### `get` all devices and `post` 2 new devices\n```python\nIn [29]: all_test = await a.dcim_devices(\n    ...:     get={},\n    ...:     post=[\n    ...:         {\n    ...:             \"name\": \"test1\",\n    ...:             \"device_role\": 1,\n    ...:             \"site\": 1,\n    ...:             \"device_type\": 1,\n    ...:             \"status\": \"planned\",\n    ...:         },\n    ...:         {\n    ...:             \"name\": \"test2\",\n    ...:             \"device_role\": 1,\n    ...:             \"site\": 1,\n    ...:             \"device_type\": 1,\n    ...:             \"status\": \"planned\",\n    ...:         },\n    ...:     ],\n    ...: )\n\n# run 3 coroutines in the event loop\nIn [30]: all_test = await asyncio.gather(*all_test)\n\n# EndpointIdIterator is an coroutine iterator with EndpointId objects\n# EndpointId is a NetBox '/dcim/devices/' object and coroutine\nIn [31]: all_test\nOut[31]: \n[EndpointIdIterator(api=Api, url='https://demo.netbox.dev/api', endpoint='/dcim/devices/'),\n EndpointId(api=Api, url='https://demo.netbox.dev/api/dcim/devices/110/', endpoint='/dcim/devices/'),\n EndpointId(api=Api, url='https://demo.netbox.dev/api/dcim/devices/111/', endpoint='/dcim/devices/')]\n\nIn [32]: all_test[0][49].name\nOut[32]: 'ncsu118-distswitch1'\n\nIn [33]: all_test[1].name\nOut[34]: 'test1'\n\nIn [35]: all_test[2].name\nOut[35]: 'test2'\n\n# httpx.Response is available with .response attribute\nIn [36]: all_test[1].response.json()\nOut[36]:\n{'id': 110,\n 'url': 'https://demo.netbox.dev/api/dcim/devices/110/',\n 'display': 'test1',\n 'name': 'test1',\n 'device_type': {'id': 1,\n  'url': 'https://demo.netbox.dev/api/dcim/device-types/1/',\n  'display': 'MX480',\n  'manufacturer': {'id': 7,\n  ...\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimeforplanb123%2Fanac","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimeforplanb123%2Fanac","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimeforplanb123%2Fanac/lists"}