Skip to content

Commit fa8d7a6

Browse files
alanbchristieAlan Christie
and
Alan Christie
authored
Initial access control logic (fs 937) (#2)
* feat: Adds creates unit and product AS API methods * feat: Working unit/product creation - Run-time ability to debug requests (SQUONK2_API_DEBUG_REQUESTS) - Adds unit/product/project example * fix: Working example unit/product/project Co-authored-by: Alan Christie <alan.christie@matildapeak.com>
1 parent cb51dd7 commit fa8d7a6

File tree

7 files changed

+388
-15
lines changed

7 files changed

+388
-15
lines changed

CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ by the GitHib Actions: -
3232

3333
And then uninstall using pip: -
3434

35-
pip uninstall im-squonk2-client
35+
pip uninstall -y im-squonk2-client
3636

3737
---
3838

README.rst

+18-2
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,19 @@ The following Squonk2 Account Server API functions are available: -
7676

7777
- ``AsApi.ping()``
7878

79-
- ``AsApi.get_version()``
79+
- ``AsApi.create_product()``
80+
- ``AsApi.create_unit()``
81+
- ``AsApi.delete_product()``
82+
- ``AsApi.delete_unit()``
8083
- ``AsApi.get_available_assets()``
8184
- ``AsApi.get_available_units()``
8285
- ``AsApi.get_available_products()``
86+
- ``AsApi.get_merchants()``
8387
- ``AsApi.get_product()``
8488
- ``AsApi.get_product_charges()``
85-
- ``AsApi.get_merchants()``
89+
- ``AsApi.get_unit()``
90+
- ``AsApi.get_units()``
91+
- ``AsApi.get_version()``
8692

8793
A ``namedtuple`` is used as the return value for many of the methods: -
8894

@@ -92,6 +98,16 @@ It contains a boolean ``success`` field and a dictionary ``msg`` field. The
9298
``msg`` typically contains the underlying REST API response content
9399
(rendered as a Python dictionary), or an error message if the call failed.
94100

101+
Debugging the API requests
102+
==========================
103+
For development purposes you can expose detailed debug information relating to
104+
the underlying API requests by setting the environment variable
105+
``SQUONK2_API_DEBUG_REQUESTS``::
106+
107+
export SQUONK2_API_DEBUG_REQUESTS=yes
108+
109+
This will enable detailed debug of both the DM and AS API calls.
110+
95111
Installation
96112
============
97113
The Squonk2 package is published on `PyPI`_ and can be installed from

examples/README.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,23 @@ Check it all works by running one of the examples: -
3131

3232
## Examples
3333

34-
### GetToken.py
34+
### get_token.py
3535
Illustrates how to get an access token from Keycloak
3636
(see the project `README.rst` on requiring a Keycloak password).
3737
That token can then be passed or used in the other examples.
3838

39-
### CalcRDkitProps.py
39+
### calc_rdkit_props.py
4040
Illustrates how to: -
4141

4242
- upload a file
4343
- run a simple job (with options) using that file
4444
- wait for the job to complete
4545
- download the results and, finally...
4646
- cleanup (delete) the job instance
47+
48+
### units_products_and_projects.py
49+
Illustrates how to: -
50+
51+
- create an Account Server (AS) organisational unit
52+
- create AS storage and data-tier products
53+
- create a project using an AS project

examples/get_token.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
parser.add_argument(
2525
"--keycloak-client-id",
2626
"-i",
27-
help='The Keycloak client ID, i.e. "data-manager-api-dev"',
27+
help='The Keycloak client ID, i.e. "data-manager-api-dev"'
28+
' or "account-server-api-dev"',
2829
required=True,
2930
)
3031
args = parser.parse_args()
+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
#!/usr/bin/env python
2+
"""An example that illustrates how to use the client to create AS
3+
Units and Products and then to create a DM project from the Product.
4+
5+
Required environment: -
6+
7+
SQUONK2_DMAPI_URL
8+
SQUONK2_ASAPI_URL
9+
KEYCLOAK_TOKEN
10+
KEYCLOAK_TOKEN_AS
11+
ORG_ID
12+
"""
13+
import os
14+
import sys
15+
16+
from squonk2.dm_api import DmApi, DmApiRv
17+
from squonk2.as_api import AsApi, AsApiRv
18+
19+
# Squonk2 authentication token and the organisation id
20+
# are taken from environment variables...
21+
as_token: str = os.environ.get("KEYCLOAK_TOKEN_AS")
22+
dm_token: str = os.environ.get("KEYCLOAK_TOKEN")
23+
org_id: str = os.environ.get("ORG_ID")
24+
25+
if as_token:
26+
print("AS token present")
27+
else:
28+
print("No AS token provided")
29+
sys.exit(1)
30+
31+
if dm_token:
32+
print("DM token present")
33+
else:
34+
print("No DM token provided")
35+
sys.exit(1)
36+
37+
if org_id:
38+
print("ORG_ID present")
39+
else:
40+
print("No ORG_ID provided")
41+
sys.exit(1)
42+
43+
# Create the unit.
44+
as_rv: AsApiRv = AsApi.create_unit(
45+
as_token,
46+
org_id=org_id,
47+
billing_day=8,
48+
unit_name="Example unit",
49+
)
50+
if not as_rv.success:
51+
print("Failed to create unit")
52+
print(as_rv)
53+
sys.exit(1)
54+
unit_id = as_rv.msg["id"]
55+
print(f"Created Unit '{unit_id}'")
56+
57+
# Create the storage product.
58+
as_rv = AsApi.create_product(
59+
as_token,
60+
product_name="Example storage",
61+
unit_id=unit_id,
62+
product_type="DATA_MANAGER_STORAGE_SUBSCRIPTION",
63+
allowance=10,
64+
limit=10,
65+
)
66+
if not as_rv.success:
67+
print("Failed to create storage product")
68+
sys.exit(1)
69+
storage_product_id = as_rv.msg["id"]
70+
print(f"Created Storage Product '{storage_product_id}'")
71+
72+
# Create the Data Tier product.
73+
# We do not set allowances on DT products.
74+
as_rv = AsApi.create_product(
75+
as_token,
76+
product_name="Example data tier",
77+
unit_id=unit_id,
78+
product_type="DATA_MANAGER_PROJECT_TIER_SUBSCRIPTION",
79+
flavour="BRONZE",
80+
)
81+
if not as_rv.success:
82+
print("Failed to create data tier product")
83+
sys.exit(1)
84+
dt_product_id = as_rv.msg["id"]
85+
print(f"Created DataTier Product '{dt_product_id}'")
86+
87+
# Create a Data Manger Project using the AS DT Product.
88+
dm_rv: DmApiRv = DmApi.create_project(
89+
dm_token,
90+
project_name="Example project",
91+
as_tier_product_id=dt_product_id,
92+
)
93+
if not dm_rv.success:
94+
print("Failed to create DM project")
95+
sys.exit(1)
96+
project_id = dm_rv.msg["project_id"]
97+
print(f"Created Project '{project_id}'")
98+
99+
# Now delete the Project, Products and unit
100+
101+
dm_rv = DmApi.delete_project(dm_token, project_id=project_id)
102+
if as_rv.success:
103+
print("Project deleted")
104+
else:
105+
print("Failed to delete product")
106+
sys.exit(1)
107+
108+
as_rv = AsApi.delete_product(as_token, product_id=dt_product_id)
109+
if as_rv.success:
110+
print("Data Tier Product deleted")
111+
else:
112+
print("Failed to delete data tier product")
113+
sys.exit(1)
114+
115+
as_rv = AsApi.delete_product(as_token, product_id=storage_product_id)
116+
if as_rv.success:
117+
print("Storage Product deleted")
118+
else:
119+
print("Failed to delete storage product")
120+
sys.exit(1)
121+
122+
as_rv = AsApi.delete_unit(as_token, unit_id=unit_id)
123+
if as_rv.success:
124+
print("Unit deleted")
125+
else:
126+
print("Failed to delete unit")
127+
sys.exit(1)

0 commit comments

Comments
 (0)