agilix-api-fr8train 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
File without changes
@@ -0,0 +1,13 @@
1
+ Metadata-Version: 2.4
2
+ Name: agilix_api_fr8train
3
+ Version: 0.1.0
4
+ Summary: Python SDK for integrating with Agilix API
5
+ Author: Tyler Collette
6
+ Author-email: t.collette@stellarvirtual.org
7
+ Requires-Python: >=3.8
8
+ License-File: LICENSE
9
+ Dynamic: author
10
+ Dynamic: author-email
11
+ Dynamic: license-file
12
+ Dynamic: requires-python
13
+ Dynamic: summary
@@ -0,0 +1,8 @@
1
+ # Agilix API
2
+ ### By fr8train-sv
3
+
4
+ A Python SDK for integrating with Agilix Buzz API. Install with:
5
+
6
+ ```bash
7
+ pip install myutils
8
+ ```
@@ -0,0 +1,142 @@
1
+ from agilix.models.connection import Connection
2
+ from agilix.factories.api import build_api_connection
3
+
4
+ from agilix.models.courses import UpdateCourseDefinition, CopyCourseDefinition
5
+
6
+
7
+ class Api:
8
+ _conn: Connection
9
+
10
+ def __init__(self):
11
+ self._conn = build_api_connection()
12
+
13
+ # PACKAGED MODULAR SCOPES
14
+ self.courses = self.Courses(self._conn)
15
+ self.domains = self.Domains(self._conn)
16
+
17
+ @staticmethod
18
+ def get_domain_id(domain_id: str, connection: Connection) -> str:
19
+ return domain_id if domain_id else connection.home_domain_id
20
+
21
+ class Courses:
22
+ _conn: Connection
23
+
24
+ def __init__(self, connection: Connection):
25
+ self._conn = connection
26
+
27
+ def list_courses(
28
+ self,
29
+ domain_id: str = "",
30
+ include_descendant_domains: bool = False,
31
+ text: str = None,
32
+ ) -> list:
33
+ query_params = {
34
+ "domainid": Api.get_domain_id(
35
+ domain_id=domain_id, connection=self._conn
36
+ ),
37
+ "includedescendantdomains": include_descendant_domains,
38
+ }
39
+
40
+ if text:
41
+ query_params["text"] = text
42
+
43
+ response = self._conn.get("listcourses", query_params)
44
+
45
+ return response.get("response", {}).get("courses", {}).get("course", [])
46
+
47
+ def get_course(self, course_id: str, select: list = []) -> dict:
48
+ params = {"courseid": course_id}
49
+
50
+ if select:
51
+ params["select"] = ",".join(select)
52
+
53
+ response = self._conn.get("getcourse2", params)
54
+
55
+ return response.get("response", {}).get("course", {})
56
+
57
+ def copy_courses(self, course_list: list[CopyCourseDefinition]) -> list:
58
+ payload = {"requests": {"course": course_list}}
59
+
60
+ response = self._conn.post("copycourses", payload=payload)
61
+
62
+ course_responses = list(
63
+ map(
64
+ lambda x: (
65
+ x.get("course", {}).get("courseid")
66
+ if x.get("code") == "OK"
67
+ else x.get("message", "Generic Error")
68
+ ),
69
+ response.get("response", {})
70
+ .get("responses", {})
71
+ .get("response", []),
72
+ )
73
+ )
74
+
75
+ return course_responses
76
+
77
+ def update_courses(self, course_list: list[UpdateCourseDefinition]) -> list:
78
+ payload = {"requests": {"course": course_list}}
79
+
80
+ response = self._conn.post("updatecourses", payload=payload)
81
+
82
+ course_responses = list(
83
+ map(
84
+ lambda x: (
85
+ x.get("code") == "OK"
86
+ if x.get("code") == "OK"
87
+ else x.get("message", "Generic Error")
88
+ ),
89
+ response.get("response", {})
90
+ .get("responses", {})
91
+ .get("response", []),
92
+ )
93
+ )
94
+
95
+ return course_responses
96
+
97
+ def delete_courses(self, course_id: list):
98
+ payload = {
99
+ "requests": {"course": list(map(lambda x: {"courseid": x}, course_id))}
100
+ }
101
+
102
+ response = self._conn.post("deletecourses", payload=payload)
103
+
104
+ course_responses = list(
105
+ map(
106
+ lambda x: (
107
+ x.get("code") == "OK"
108
+ if x.get("code") == "OK"
109
+ else x.get("message", "Generic Error")
110
+ ),
111
+ response.get("response", {})
112
+ .get("responses", {})
113
+ .get("response", []),
114
+ )
115
+ )
116
+
117
+ return course_responses
118
+
119
+ class Domains:
120
+ _conn: Connection
121
+
122
+ def __init__(self, connection: Connection):
123
+ self._conn = connection
124
+
125
+ def list_domains(
126
+ self,
127
+ domain_id: str = "",
128
+ include_descendant_domains: bool = False,
129
+ limit: int = 100,
130
+ ) -> list:
131
+ response = self._conn.get(
132
+ "listdomains",
133
+ {
134
+ "domainid": Api.get_domain_id(
135
+ domain_id=domain_id, connection=self._conn
136
+ ),
137
+ "includedescendantdomains": include_descendant_domains,
138
+ "limit": limit,
139
+ },
140
+ )
141
+
142
+ return response.get("response", {}).get("domains", {}).get("domain", [])
@@ -0,0 +1,48 @@
1
+ from dotenv import load_dotenv
2
+ from agilix.models.connection import Connection
3
+ import os
4
+ import requests
5
+
6
+
7
+ def build_api_connection() -> Connection:
8
+ load_dotenv(override=True)
9
+
10
+ base_url = os.getenv("BASE_URL")
11
+ username = os.getenv("USERNAME")
12
+ password = os.getenv("PASSWORD")
13
+ domain = os.getenv("DOMAIN")
14
+ home_domain_id = os.getenv("HOME_DOMAIN_ID")
15
+
16
+ session = requests.Session()
17
+ session.headers.update({
18
+ "Content-Type": "application/json",
19
+ "Accept": "application/json"
20
+ })
21
+
22
+ json_payload = {
23
+ "request": {
24
+ "cmd": "login3",
25
+ "username": f"{domain}/{username}",
26
+ "password": password
27
+ }
28
+ }
29
+
30
+ response = session.post(base_url, json=json_payload)
31
+ response.raise_for_status()
32
+ login_data = response.json()
33
+
34
+ login_token = login_data.get('response', {}).get('user', {}).get('token', None)
35
+
36
+ if login_token is None:
37
+ error_code = login_data.get('response', {}).get('code', "Generic Error")
38
+ error_message = login_data.get('response', {}).get('message', "Generic Error")
39
+ raise Exception(f"{error_code}: {error_message}")
40
+
41
+ conn = Connection(
42
+ base_url=base_url,
43
+ session=session,
44
+ token=login_token,
45
+ home_domain_id=home_domain_id
46
+ )
47
+
48
+ return conn
@@ -0,0 +1,53 @@
1
+ from requests import Session
2
+ from urllib.parse import urlencode
3
+
4
+ class Connection:
5
+ token: str
6
+ session: Session
7
+ base_url: str
8
+ home_domain_id: str
9
+
10
+ def __init__(self, token: str = "",
11
+ base_url: str = "",
12
+ home_domain_id: str = "",
13
+ session: Session = Session()):
14
+ self.token = token
15
+ self.base_url = base_url
16
+ self.session = session
17
+ self.home_domain_id = home_domain_id
18
+
19
+
20
+ def get(self,
21
+ cmd: str,
22
+ params: dict = {}):
23
+ query_string = urlencode({ 'cmd': cmd, '_token': self.token } | params, doseq=True)
24
+
25
+ response = self.session.get(f"{self.base_url}?{query_string}")
26
+ response.raise_for_status()
27
+
28
+ if response.status_code != 200:
29
+ raise Exception(f"Error: {response.status_code} - {response.text}")
30
+
31
+ return response.json()
32
+
33
+ def post(self,
34
+ cmd: str,
35
+ params: dict = {},
36
+ payload: dict = {}):
37
+ query_string = ""
38
+
39
+ if cmd:
40
+ query_string = urlencode({ 'cmd': cmd, '_token': self.token } | params, doseq=True)
41
+ else:
42
+ payload = {'_token': self.token} | payload
43
+ if bool(params):
44
+ query_string = urlencode(params, doseq=True)
45
+
46
+ target_url = f"{self.base_url}?{query_string}" if query_string else self.base_url
47
+
48
+ # NEED TO DO A POST PAYLOAD WITH THE TOKEN ADDED TO THE REQUESTS OBJECT
49
+
50
+ response = self.session.post(target_url, json=payload)
51
+ response.raise_for_status()
52
+
53
+ return response.json()
@@ -0,0 +1,42 @@
1
+ class UpdateCourseDefinition:
2
+ course_id: str
3
+ domain_id: str
4
+ title: str
5
+ reference: str
6
+
7
+ def __init__(self,
8
+ course_id: str,
9
+ domain_id: str,
10
+ title: str,
11
+ reference: str):
12
+ self.course_id = course_id
13
+ self.domain_id = domain_id
14
+ self.title = title
15
+ self.reference = reference
16
+
17
+
18
+ def __iter__(self):
19
+ yield "courseid", self.course_id
20
+ yield "domainid", self.domain_id
21
+ yield "title", self.title
22
+ yield "reference", self.reference
23
+
24
+
25
+ class CopyCourseDefinition:
26
+ course_id: str
27
+ domain_id: str
28
+ action: str
29
+ reference: str
30
+ status: int
31
+
32
+ def __init__(self,
33
+ course_id: str,
34
+ domain_id: str,
35
+ action: str = 'StaticCopy',
36
+ reference: str = '',
37
+ status: int = 0):
38
+ self.course_id = course_id
39
+ self.domain_id = domain_id
40
+ self.action = action
41
+ self.reference = reference
42
+ self.status = status
@@ -0,0 +1,13 @@
1
+ Metadata-Version: 2.4
2
+ Name: agilix_api_fr8train
3
+ Version: 0.1.0
4
+ Summary: Python SDK for integrating with Agilix API
5
+ Author: Tyler Collette
6
+ Author-email: t.collette@stellarvirtual.org
7
+ Requires-Python: >=3.8
8
+ License-File: LICENSE
9
+ Dynamic: author
10
+ Dynamic: author-email
11
+ Dynamic: license-file
12
+ Dynamic: requires-python
13
+ Dynamic: summary
@@ -0,0 +1,16 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ setup.py
5
+ agilix_api_fr8train/__init__.py
6
+ agilix_api_fr8train/api.py
7
+ agilix_api_fr8train.egg-info/PKG-INFO
8
+ agilix_api_fr8train.egg-info/SOURCES.txt
9
+ agilix_api_fr8train.egg-info/dependency_links.txt
10
+ agilix_api_fr8train.egg-info/top_level.txt
11
+ agilix_api_fr8train/factories/__init__.py
12
+ agilix_api_fr8train/factories/api.py
13
+ agilix_api_fr8train/models/__init__.py
14
+ agilix_api_fr8train/models/connection.py
15
+ agilix_api_fr8train/models/courses.py
16
+ tests/test_api.py
@@ -0,0 +1 @@
1
+ agilix_api_fr8train
@@ -0,0 +1,3 @@
1
+ [build-system]
2
+ requires = ["setuptools", "wheel"]
3
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,12 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="agilix_api_fr8train", # Must be unique on PyPI!
5
+ version="0.1.0",
6
+ description="Python SDK for integrating with Agilix API",
7
+ author="Tyler Collette",
8
+ author_email="t.collette@stellarvirtual.org",
9
+ packages=find_packages(),
10
+ install_requires=[], # Add dependencies here
11
+ python_requires=">=3.8",
12
+ )
File without changes