|
1 | | -# python-hde [](https://codecov.io/gh/becelot/python-hde) |
| 1 | +# Hosting.de Client-Library |
| 2 | + |
| 3 | +An unofficial client library for the [hosting.de API](https://hosting.de/api/). |
| 4 | + |
| 5 | +- API Version: v1 |
| 6 | +- Package version: 0.0.1 |
| 7 | + |
| 8 | +## Requirements |
| 9 | + |
| 10 | +The package requires Python 3.6+. It is currently only tested with Python 3.8, but should work for Python 3.6. |
| 11 | + |
| 12 | +## Installation & Usage |
| 13 | + |
| 14 | +The package is currently not hosted publicly, but will be initially. There is no `pip install` **yet**. |
| 15 | + |
| 16 | +### Setuptools |
| 17 | + |
| 18 | +Install via [Setuptools](http://pypi.python.org/pypi/setuptools). Clone this repository and run |
| 19 | + |
| 20 | +```sh |
| 21 | +python setup.py install --user |
| 22 | +``` |
| 23 | +(or `sudo python setup.py install` to install the package for all users) |
| 24 | + |
| 25 | +Then import the package: |
| 26 | +```python |
| 27 | +import python_hde |
| 28 | +``` |
| 29 | + |
| 30 | +## Getting Started |
| 31 | + |
| 32 | +Please follow the [installation procedure](#installation--usage). To login with the client, you need your endpoint |
| 33 | +url, and an API token. To authenticate: |
| 34 | + |
| 35 | +```python |
| 36 | +from python_hde import api |
| 37 | +from python_hde.client import HostingDeClient |
| 38 | + |
| 39 | +client: HostingDeClient = api.login('<your endpoint url>', '<your token>') |
| 40 | +``` |
| 41 | + |
| 42 | +Your endpoint should look like this: `https://<your_domain>/api` (do not forget the `/api` while providing the endpoint). |
| 43 | + |
| 44 | +The client is modularized into the different service types, for example `client.dns` refers to the DNS service API. |
| 45 | + |
| 46 | +For example, to fetch all zones, you can use: |
| 47 | + |
| 48 | +```python |
| 49 | +from python_hde import api |
| 50 | +from python_hde.client import HostingDeClient |
| 51 | + |
| 52 | +client: HostingDeClient = api.login('<your endpoint url>', '<your token>') |
| 53 | + |
| 54 | +for zone in client.dns.list_zones(): |
| 55 | + print(zone) |
| 56 | +``` |
| 57 | + |
| 58 | +All implemented endpoints are fully documented and typed. You will get corresponding hints in your IDE of choice. |
| 59 | + |
| 60 | +### Filtering and Sorting API |
| 61 | + |
| 62 | +In order to use filter and sort APIs, we simplified the usage of the API. For example, to search for a specific zone: |
| 63 | + |
| 64 | +```python |
| 65 | +from python_hde import api |
| 66 | +from python_hde.client import HostingDeClient |
| 67 | +from python_hde.model.filter import FilterCondition |
| 68 | + |
| 69 | +client: HostingDeClient = api.login('<your endpoint url>', '<your token>') |
| 70 | + |
| 71 | +zone_filter = FilterCondition('zoneName').eq('example.com') |
| 72 | + |
| 73 | +for zone in client.dns.list_zones(filter=zone_filter): |
| 74 | + print(zone) |
| 75 | +``` |
| 76 | + |
| 77 | +This will automatically build teh corresponding filter expression in the background |
| 78 | + |
| 79 | +```json |
| 80 | +{ |
| 81 | + "field": "domainName", |
| 82 | + "value": "example.com", |
| 83 | + "relation": "equal" |
| 84 | +} |
| 85 | +``` |
| 86 | + |
| 87 | +Apart from `FilterCondition.eq`, the condition supports all relations currently defined in the API: |
| 88 | + |
| 89 | +| Relation | Operation | Description | |
| 90 | +|--------------|----------------------------|----------------------------------------------------------------------------------------------------------------| |
| 91 | +| equal | FilterCondition.eq | `field` must match value exactly | |
| 92 | +| unequal | FilterCondition.ne | `field` must not be the same as value | |
| 93 | +| greater | FilterCondition.gt | `field` must be greater than value. This might apply to e.g. an integer value, a date or a date time | |
| 94 | +| less | FilterCondition.lt | `field` must be less than value. This might apply to e.g. an integer value, a date or a date time | |
| 95 | +| greaterEqual | FilterCondition.ge | `field` must be greater than or equal to value. This might apply to e.g. an integer value, a date or a date time | |
| 96 | +| lessEqual | FilterCondition.le | `field` must be less than or equal to value. This might apply to e.g. an integer value, a date or a date time | |
| 97 | +| | FilterCondition.startswith | Corresponds to the `field` method. However, uses wildcard to simplify the usage --> `field*` | |
| 98 | + |
| 99 | +Chaining filters is easily supported as well: |
| 100 | + |
| 101 | +```python |
| 102 | +from python_hde import api |
| 103 | +from python_hde.client import HostingDeClient |
| 104 | +from python_hde.model.filter import FilterCondition |
| 105 | + |
| 106 | +client: HostingDeClient = api.login('<your endpoint url>', '<your token>') |
| 107 | + |
| 108 | +zone_filter = (FilterCondition('zoneName').startswith('example') | FilterCondition('zoneName').startswith('demo')) & FilterCondition('zoneName').ne('*.com') |
| 109 | + |
| 110 | +for zone in client.dns.list_zones(filter=zone_filter): |
| 111 | + print(zone) |
| 112 | +``` |
| 113 | + |
| 114 | +This automatically builds the equivalent filter expression for the API: |
| 115 | + |
| 116 | +```json |
| 117 | +{ |
| 118 | + "subFilterConnective": "AND", |
| 119 | + "subFilter": [ |
| 120 | + { |
| 121 | + "subFilterConnective": "OR", |
| 122 | + "subFilter": [ |
| 123 | + { |
| 124 | + "field": "zoneName", |
| 125 | + "value": "example*", |
| 126 | + "relation": "equal" |
| 127 | + }, |
| 128 | + { |
| 129 | + "field": "zoneName", |
| 130 | + "value": "demo*", |
| 131 | + "relation": "equal" |
| 132 | + } |
| 133 | + ] |
| 134 | + }, |
| 135 | + { |
| 136 | + "field": "zoneName", |
| 137 | + "value": "*.com", |
| 138 | + "relation": "unequal" |
| 139 | + } |
| 140 | + ] |
| 141 | +} |
| 142 | +``` |
| 143 | + |
| 144 | +but is less verbose and more readable. |
| 145 | + |
| 146 | +### Error Handling |
| 147 | + |
| 148 | +If the request returns an error, the error is wrapped inside a `api.client.exceptions.APIException` with all |
| 149 | +details included. You can easily catch them and react to them accodringly. |
| 150 | + |
| 151 | +## Current status |
| 152 | + |
| 153 | +Currently, we support the following endpoints for the following services: |
| 154 | + |
| 155 | +* DNS |
| 156 | + * [x] list_zones 100% |
| 157 | + * [x] list_zone_configs 100% |
| 158 | + * [x] list_records 100% |
| 159 | + * [x] delete_zone 100% |
| 160 | + * [ ] jobs_find 50% - missing official documentation, functionality cannot be guaranteed |
| 161 | + * [x] update_zone 100% |
| 162 | +* Account |
| 163 | + * [ ] list_accounts 50% - missing official documentation, functionality cannot be guaranteed |
| 164 | + |
| 165 | +We plan to add more endpoints in the future, for example for SSL and Domain services. |
| 166 | + |
| 167 | +The implemented endpoints do not contain any logic to catch asynchronous behaviour yet. We plan to add a `sync: bool` |
| 168 | +property to the corresponding endpoints in the future as soon as the jobs API is properly defined. |
| 169 | + |
| 170 | +## Developing |
| 171 | + |
| 172 | +Make sure that you satisfy the [requirements](#requirements). Checkout the project, then run |
| 173 | + |
| 174 | +```shell |
| 175 | +pip install -r requirements.txt |
| 176 | +pip install -r requirements-test.txt |
| 177 | +``` |
| 178 | + |
| 179 | +preferably in a virtual environment. |
| 180 | + |
| 181 | +This will install all dependencies for the main project, as well as the dependencies used for testing. |
| 182 | + |
| 183 | +### Testing |
| 184 | + |
| 185 | +Run |
| 186 | + |
| 187 | +```shell |
| 188 | +pytest -vv --cov-report term-missing:skip-covered --cov=api --cov=utils --cov-report xml --html=test-results/report.html --cov-report html:test-results/cov |
| 189 | +``` |
| 190 | + |
| 191 | +in order to test the code. |
| 192 | + |
| 193 | +## Contributing |
| 194 | + |
| 195 | +You can contribute to the project and add new endpoints that you need. However, in order to merge, we require: |
| 196 | + |
| 197 | +* All implemented methods **MUST** be documented using reStructuredText notation. |
| 198 | +* All implemented methods **MUST** be typed properly |
| 199 | +* We require a test coverage of at least 90%, and your additions must not decrease the overall coverage of the codebase. |
| 200 | +* We appreciate if you use [this](https://github.com/angular/angular/blob/master/CONTRIBUTING.md) commit message format. |
0 commit comments