Implemented devops decorator and a get method that retrieves object properties by a key.
All checks were successful
/ unit-tests (push) Successful in 10s
All checks were successful
/ unit-tests (push) Successful in 10s
This commit is contained in:
32
sk/devops.py
32
sk/devops.py
@@ -2,12 +2,13 @@ from __future__ import annotations
|
|||||||
import requests
|
import requests
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
from string import Template
|
||||||
|
|
||||||
DEVOPS_SCOPE = "https://app.vssps.visualstudio.com/.default"
|
DEVOPS_SCOPE = "https://app.vssps.visualstudio.com/.default"
|
||||||
DEVOPS_API_VERSION = "7.1"
|
DEVOPS_API_VERSION = "7.1"
|
||||||
|
|
||||||
# Define a class decorator
|
# Define a class decorator
|
||||||
def auto_properties(mapping: dict[str,str] | None = None):
|
def auto_properties(mapping: dict[str,str]):
|
||||||
|
|
||||||
def make_property(name: str):
|
def make_property(name: str):
|
||||||
private_var = f"_{name}"
|
private_var = f"_{name}"
|
||||||
@@ -53,6 +54,15 @@ def auto_properties(mapping: dict[str,str] | None = None):
|
|||||||
return cls
|
return cls
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
def devops(key: str, get_url: str, list_url: str = None, params: dict = {}):
|
||||||
|
def decorator(cls):
|
||||||
|
cls.__entity_key__ = key
|
||||||
|
cls.__entity_get_url__ = get_url # Use $key in the URL
|
||||||
|
cls.__entity_list_url__ = list_url # Use $key in the URL
|
||||||
|
cls.__entity_params__ = params
|
||||||
|
return cls
|
||||||
|
return decorator
|
||||||
|
|
||||||
class DevOps():
|
class DevOps():
|
||||||
"""Base class for DevOps entities."""
|
"""Base class for DevOps entities."""
|
||||||
|
|
||||||
@@ -77,7 +87,24 @@ class DevOps():
|
|||||||
r.raise_for_status() # Ensure we raise an error for bad responses
|
r.raise_for_status() # Ensure we raise an error for bad responses
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def _get_entity(self, key_name: str, get_url: str, params: dict = {}) -> object:
|
def _get(self, key: str):
|
||||||
|
if not hasattr(self.__class__, "__entity_key__") or not hasattr(self.__class__, "__entity_get_url__"):
|
||||||
|
raise NotImplementedError("Called _get on a class that has not been decorated with @devops.")
|
||||||
|
setattr(self, f"_{self.__class__.__entity_key__}", key) # Set the entity key
|
||||||
|
# Build the URL
|
||||||
|
url = Template(self.__class__.__entity_get_url__).substitute(key=key)
|
||||||
|
# Build parameters with key substituted
|
||||||
|
params = {}
|
||||||
|
if hasattr(self.__class__, "__entity_params__"):
|
||||||
|
params = {k: Template(v).substitute(key=key) for k, v in self.__class__.__entity_params__.items()}
|
||||||
|
|
||||||
|
# Fetch the object data from the URL
|
||||||
|
r = self._get_url_path(url, params=params)
|
||||||
|
|
||||||
|
# Populate attributes
|
||||||
|
self.from_json(r.json())
|
||||||
|
|
||||||
|
def _get_entity(self, key_name: str, get_url: str, params: dict = {}):
|
||||||
"""
|
"""
|
||||||
Each entity class can use this method to populate its attributes, by defining
|
Each entity class can use this method to populate its attributes, by defining
|
||||||
its own _get method that calls this one with the key name,
|
its own _get method that calls this one with the key name,
|
||||||
@@ -129,6 +156,7 @@ class Organization(DevOps):
|
|||||||
"url": "url",
|
"url": "url",
|
||||||
"description": "description"
|
"description": "description"
|
||||||
})
|
})
|
||||||
|
@devops("id", "_apis/projects/$key", "_apis/projects")
|
||||||
class Project(DevOps):
|
class Project(DevOps):
|
||||||
def _get(self):
|
def _get(self):
|
||||||
self._get_entity(
|
self._get_entity(
|
||||||
|
|||||||
Reference in New Issue
Block a user