{"id":25072454,"url":"https://github.com/upcloudltd/upcloud-python-api","last_synced_at":"2025-05-15T12:07:07.181Z","repository":{"id":29041356,"uuid":"32568910","full_name":"UpCloudLtd/upcloud-python-api","owner":"UpCloudLtd","description":"Python client for UpCloud's API","archived":false,"fork":false,"pushed_at":"2024-12-02T12:27:27.000Z","size":771,"stargazers_count":53,"open_issues_count":3,"forks_count":21,"subscribers_count":17,"default_branch":"main","last_synced_at":"2025-05-15T12:07:01.701Z","etag":null,"topics":["api-client","pypi","python","upcloud","upcloud-api"],"latest_commit_sha":null,"homepage":null,"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/UpCloudLtd.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-03-20T07:18:44.000Z","updated_at":"2024-12-02T12:17:05.000Z","dependencies_parsed_at":"2023-12-31T15:25:14.629Z","dependency_job_id":"cae0e8dd-eb72-43c0-af7c-ec7653f20958","html_url":"https://github.com/UpCloudLtd/upcloud-python-api","commit_stats":{"total_commits":278,"total_committers":25,"mean_commits":11.12,"dds":0.6942446043165468,"last_synced_commit":"f80d8f6f15af2538b8708a2d61ab1eba1726f342"},"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UpCloudLtd%2Fupcloud-python-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UpCloudLtd%2Fupcloud-python-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UpCloudLtd%2Fupcloud-python-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UpCloudLtd%2Fupcloud-python-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/UpCloudLtd","download_url":"https://codeload.github.com/UpCloudLtd/upcloud-python-api/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254337612,"owners_count":22054254,"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":["api-client","pypi","python","upcloud","upcloud-api"],"created_at":"2025-02-06T22:29:21.257Z","updated_at":"2025-05-15T12:07:02.163Z","avatar_url":"https://github.com/UpCloudLtd.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# UpCloud's Python API Client\n\n[![test](https://github.com/UpCloudLtd/upcloud-python-api/actions/workflows/main.yml/badge.svg)](https://github.com/UpCloudLtd/upcloud-python-api/actions/workflows/main.yml)\n[![PyPI version](https://badge.fury.io/py/upcloud-api.svg)](https://badge.fury.io/py/upcloud-api)\n[![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/UpCloudLtd/upcloud-python-api/blob/main/LICENSE.txt)\n\nOOP-based API client for [UpCloud's API](https://developers.upcloud.com/1.3/). Includes most of the API\nfunctionality and some convenience functions that combine several API endpoints and logic.\n\nPlease test all of your use cases thoroughly before actual production use. Using a separate UpCloud account for\ntesting / developing the client is recommended.\n\n## Installation\n\n``` bash\npip install upcloud-api\n```\n\nAlternatively, if you want the newest (possibly not yet released) stuff, clone the project and run:\n\n``` bash\npython setup.py install\n```\n\n### Supported Python versions in API v2.6.0\n\n- Python 3.9\n- Python 3.10\n- Python 3.11\n- Python 3.12\n- Python 3.13\n- PyPy3\n\n**Python 2 has been deprecated**\n\n- Python 2.7 is no longer supported, but available in older API versions (\u003c v2.0.0).\n\n## Changelog\n\n- Changelog is available [in its own file](CHANGELOG.md)\n\n## Usage\n\nMore usage examples are available under [docs/]. If there's a specific thing you're interested in,\nbut are not able to get working, please [contact UpCloud support](https://upcloud.com/contact/).\n\n### Defining and creating servers\n\n```python\n\nimport upcloud_api\nfrom upcloud_api import CloudManager, Server, Storage, login_user_block\n\nmanager = CloudManager('api_user', 'password')\nmanager.authenticate()\n\n\nlogin_user = login_user_block(\n    username='theuser',\n    ssh_keys=['ssh-rsa AAAAB3NzaC1yc2EAA[...]ptshi44x user@some.host'],\n    create_password=False\n)\n\ncluster = {\n    'web1': Server(\n        plan='2xCPU-4GB',\n        hostname='web1.example.com',\n        zone='uk-lon1', # All available zones with ids can be retrieved by using manager.get_zones()\n        storage_devices=[\n            # OS: template storage UUID, all available os templates can be retrieved by calling manager.get_templates()\n            # Note: the storage os template uuid:s will change when OS is updated. So check that the UUID is correct\n            # default tier: maxIOPS, the 100k IOPS storage backend\n            Storage(os='01000000-0000-4000-8000-000030240200', size=10),\n            # secondary storage, hdd for reduced speed \u0026 cost\n            Storage(size=100, tier='hdd')\n        ],\n        login_user=login_user  # user and ssh-keys\n    ),\n    'web2': Server(\n        plan='2xCPU-4GB',\n        hostname='web2.example.com',\n        zone='uk-lon1',\n        storage_devices=[\n            Storage(os='01000000-0000-4000-8000-000030240200', size=10),\n            Storage(size=100, tier='hdd'),\n        ],\n        login_user=login_user\n    ),\n    'db': Server(\n        # use custom resources, instead of a plan\n        core_number=12, # CPU cores\n        memory_amount=49152, # RAM in MB\n        hostname='db.example.com',\n        zone='uk-lon1',\n        storage_devices=[\n            Storage(os='01000000-0000-4000-8000-000030240200', size=10),\n            Storage(size=100),\n        ],\n        login_user=login_user\n    ),\n    'lb': Server(\n        plan='2xCPU-4GB',\n        hostname='balancer.example.com',\n        zone='uk-lon1',\n        storage_devices=[\n            Storage(os='01000000-0000-4000-8000-000030240200', size=10)\n        ],\n        login_user=login_user\n    )\n}\n\nfor server in cluster:\n    manager.create_server(cluster[server]) # creates all server objects defined in cluster\n\n```\n\nServers can be defined as dicts without using Server or Storage classes.\nThe syntax/attributes are exactly like above and under the hood they are converted to Server and Storage classes.\nThis feature is mainly for easier usage of the module from Ansible, but may provide useful elsewhere.\n\n### Stop / Start / Destroy Servers\n\n```python\nfor server in cluster:\n\tserver.shutdown()\n\t# OR:\n\tserver.start()\n\t# OR:\n\tserver.destroy()\n\tfor storage in server.storage_devices:\n\t  storage.destroy()\n\n```\n\nAs the success of server.start() or server.destroy() and storage.destroy()\ndepend on the Server's `state`, new helpers have been added. The helpers may be called regardless of\nthe server's current state.\n\n```python\n# makes sure that the server is stopped (blocking wait) and then destroys the server and its storages\nserver.stop_and_destroy()\n\n# makes sure that the server is started (blocking wait)\nserver.ensure_started()\n```\n\nCloudManager offers mode fine-grained deletion options for servers as you can choose to delete storages and\nchoose what happens to their backups when deleting the server. By default the storage and their backups are\nalways preserved.\n\nFollowing example would delete all storages attached to a server, but would keep the latest backup\nof each storage if backups exist.\n\n```python\n\nfrom upcloud_api.storage import BackupDeletionPolicy\n\nmanager.delete_server(uuid, delete_storages=True, backups=BackupDeletionPolicy.KEEP_LATEST)\n\n```\n\n### Upgrade a Server\n\n```python\n\nserver = cluster['web1']\nserver.shutdown()\nserver.core_number = 4\nserver.memory_amount = 4096\nserver.save()\nserver.start()\n\n```\n\n### Clone a new server from existing storage\n\nCloning is done by giving existing storage uuid to storage_devices. Note that size of the storage\nmust be defined and must be at least the same size as the storage being cloned.\n\n```python\nclone = Server(\n    plan='2xCPU-4GB',\n    hostname='cloned.server',\n    zone='fi-hel1',\n    storage_devices=[\n        Storage(\n            uuid='012bea57-0f70-4154-84d0-b3d25f4a018b',\n            size=50  # size must be defined and it has to be at least same size than storage being cloned\n        ),\n    ]\n)\n\nmanager.create_server(clone)\n```\n\n### Easy access to servers and their information\n\n```python\n\n# returns a public IPv4 (preferred) IPv6 (no public IPv4 was attached) address\nserver.get_public_ip()\n\n# returns a JSON serializable dict with the server's information (storages and ip-addresses included)\nserver.to_dict()\n\n```\n\n### Get resources\n\n```python\n\nservers     = manager.get_servers()\nserver1     = manager.get_server(uuid) # e.g servers[0].uuid\nstorages    = manager.get_storages()\nstorage1    = manager.get_storage(uuid) # e.g server1.storage_devices[0].uuid\nip_addrs    = manager.get_ips()\nip_addr     = manager.get_ip(address) # e.g server1.ip_addresses[0].address\n\n```\n\n## Testing\n\nSet up environment and install dependencies:\n\n``` bash\n# run at project root, python3 and virtualenv must be installed\nvirtualenv venv\nsource venv/bin/activate\n```\n\nInstall the package in editable mode.\n\n```bash\n# run at project root\npip install -e .\n```\n\nTests are located under `test/`. Run with:\n\n```bash\npy.test test/\n```\n\nTo test against all supported python versions, run:\n\n```bash\ntox\n```\n\n\nThe project also supplies a small test suite to test against the live API in `test/test_integration`.\nThis suite is NOT run with `py.test` dy default as it will permanently remove all resources related to an account.\nIt should only be run with a throwaway dev-only account when preparing for a new release. It is not shipped with\nPyPI releases. To run the integration tests, append `--integration-tests` flag to the `py.test` command.\n\n## Bugs, Issues, Problems, Ideas\n\nPlease report issues and features requests through\n[the issues page](https://github.com/UpCloudLtd/upcloud-python-api/issues).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fupcloudltd%2Fupcloud-python-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fupcloudltd%2Fupcloud-python-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fupcloudltd%2Fupcloud-python-api/lists"}