hudu-magic
The Official tiny, enum-driven, class-based Python API client for Hudu.
- Minimal dependencies (requests)
- Generated from OpenAPI
- Low Maintenance
- Designed for clarity and maintainability
Quick Start
from hudu_magic import HuduClient
client = HuduClient(
api_key="your_api_key",
instance_url="https://yourinstance.huducloud.com"
)
company = client.companies.create(name="Test Company")
# Use a real asset_layout_id from your Hudu instance (e.g. from client.asset_layouts.list()).
asset = client.assets.create(
company_id=company.id,
name="Router",
asset_layout_id=1,
)
asset.name = "Updated Router"
asset.save()
asset.delete()
Installation
Install package
pip install hudu-magic
Usage Info and Guide
There are several examples in the examples folder that might be helpful if you're just starting out
Core Concepts
Client
Handles auth, requests, pagination, wrapping.
client.assets.list()
Collections
Collection-level operations:
- list()
- get()
- create()
- delete()
- archive()
- unarchive()
assetsforcompany.save()
assetsforcompany.delete()
assetsforcompany.archive()
Models (HuduObject)
Instance-level operations:
- save()
- delete()
- refresh()
- relate_to()
- list_photos()
- list_uploads()
- relate_to()
- upload_to()
- add_label() / assign_label()
- list_labels()
- strip_labels()
asset.save()
asset.delete()
asset.add_label(priority_type)
Special Model Methods
Assets
someasset.add_public_photo("smile.png")
someasset.add_photo("dogslaughing.jpeg")
some objects can be attributed directly to or uploaded to assets
Companies
mycompany.list_assets()
mycompany.list_articles()
mycompany.list_passwords()
mycompany.list_procedures()
mycompany.list_websites()
mycompany.list_folders()
mycompany.list_password_folders()
mycompany.create_website()
mycompany.create_password()
mycompany.create_procedure()
mycompany.create_article()
mycompany.create_asset()
objects that require or can be attributed to a company often can be listed or created directly from a company object
Exports
starting a CSV or PDF export
newexport = client.exports.start(format="pdf", company_id=1, asset_layout_ids=[2],
include_passwords= True,
include_websites= True,
include_articles= True,
include_archived_articles= True,
include_archived_passwords= True,
include_archived_websites= True,
include_archived_assets= True,
)
client.Exports.new() is aliased to client.Exports.start()
csvexport = client.exports.start(format="csv",company_id=mycompany.id)
pdfexport = client.exports.start(format="pdf",company_id=mycompany.id)
Friendly defaults on create
the include_* options here default to true if not provided
the asset layout array defaults to all layouts found with HuduClient.asset_layouts.list are included.
Checking status of export
blocking-check on export status
ready = client.exports.wait_until_downloadable(newexport, interval=2.0, timeout=3600)
someexport.wait_until_downloadable(interval=5.0, timeout=600)
downloading exports
download = client.exports.download(newexport.id, "/home/myoutputfolder")
download = client.exports.download(otherexportobject) # download to current working dir
someexportobject.download() # download to current working dir
myexportobject.download("/home/myoutputfolder")
Asset Layouts and Fields
AssetLayout.to_create_payload() builds the same JSON body as normalize_layout_for_create on that layout’s underlying data. Prefer to_create_payload whenever you already have (or can wrap) an AssetLayout. Use normalize_layout_for_create only when you have a plain dict and no instance yet (for example after json.load).
Clone an existing layout (GET-shaped data normalized for POST):
mylayout = client.asset_layouts.get(2)
payload = mylayout.to_create_payload()
payload["name"] = "Updated New Layout"
newlayout = client.asset_layouts.create(payload=payload)
print(f"created new layout: {newlayout.name}")
Create a layout from scratch by wrapping a draft dict in AssetLayout, then calling to_create_payload. You can omit position on fields; contiguous positions and icon / include defaults are applied for you. For ListSelect fields you need a real list_id from your instance.
from hudu_magic.endpoints import HuduEndpoint
from hudu_magic.models import AssetLayout
draft = AssetLayout(
client,
HuduEndpoint.ASSET_LAYOUTS,
{
"name": "Docking stations",
"fields": [
{"label": "Asset tag", "field_type": "Text"},
{"label": "Room", "field_type": "Text"},
],
},
)
payload = draft.to_create_payload()
layout = client.asset_layouts.create(payload=payload)
Dict only, no AssetLayout yet (same payload shape as above):
from hudu_magic import normalize_layout_for_create
layout_dict = {"name": "Docking stations", "fields": [{"label": "x", "field_type": "Text"}]}
payload = normalize_layout_for_create(layout_dict)
# pass `payload` to client.asset_layouts.create(payload=payload) when you have a client
Layout Fields
Below are the valid layout field types (as of May11, 2026). These fields have different requirements and validation is intentionally somewhat loose for most of these, so that any error codes present will be reflected directly by Hudu itself. Not to worry, however, Hudu field validation does not change wildly.
- Text
- Number
- CheckBox
- Website
- AssetTag
- Phone
- Date
- RichText
- Heading
- Password
- ListSelect
Website fields (which require https:// prefix) are automagically handled Number fields must be an integer, but we safely coerce when possible from float, double, oer either as number-string ("1" or "44.7")
Procedures (processes) and tasks
The API and OpenAPI 2.41.0 use process / run wording; this library still exposes Procedure / procedure_tasks and the client.procedure / client.procedure_tasks aliases (client.process, client.tasks, etc.).
myprocedure.kick_off()
myprocedure.kickoff()
myprocedure.start()
myprocedure.is_run #bool property
companyprocedures = mycompany.list_procedures()
procedures = client.procedures.list()
myprocedure = client.procedures.create(payload={"name": "asdf", "company_id": 1})
myprocedure.add_task(name="newtask", auto_kickoff=True)
client.procedure_task.create(name="newtask", procedure_id=myprocedure.id)
# One procedure only — not on .list() results
proc = client.procedures.get(id=1)
proc.add_task(name="Step 1", auto_kickoff=True)
someprocedure.list_tasks()
someotherprocedure.tasks
sometask.assign_to(mypersonaluser)
Calling kick_off, kickoff, or start returns a new run (still a Procedure with is_run true). Runs share the same model as templates but behave differently for tasks.
Use is_run to tell a template from a run.
Creating tasks (POST /procedure_tasks) is for process (template) tasks only: supported body fields include name, description, procedure_id, position, optional, and parent_task_id. You cannot set assignees or run-only fields on create; kick off the process first, then set due_date, priority, and assigned_users on the run task via PUT /procedure_tasks/{id}, or use Users.assign_task (which updates assigned_users on the run task).
Updating a procedure/run (PUT /procedures/{id}) accepts name, description, and archived (company processes only for archiving). It no longer accepts moving a process between companies via company_id or legacy company_template on PATCH—use create/duplicate flows per Hudu’s API.
POST / PUT /procedures use a flat JSON body ({"name": "...", "company_id": ...}), not a nested procedure object—this matches Hudu 2.39.6+ and avoids 422 “Name can’t be blank” if the server ignored the old wrapper.
Paginated GET /procedures responses are normalized to a HuduCollection even when only one row is returned (so len() is a row count and for p in … yields Procedure objects, not attribute names). List payloads may use procedures or processes as the collection key.
Procedure.save() sends only those allowed fields so validation matches the spec.
Use Procedure.add_task(...) to create a template task (optional auto_kickoff=True after create). Run-only fields belong on the run task after kickoff.
Users
myuser.assign_task(thistask)
myotheruser.assign_task(client.procedure_tasks.get(56))
You can assign a run task from a Users instance or call task.assign_to(user); both use assigned_users on the run task.
Labels and label types
Labels attach a label type to a labelable record. Labelable types (see LABELABLE_TYPES in constants.py) are:
Article, Asset, AssetPassword, Website, IpAddress, Vlan, VlanZone, Procedure, Network, RackStorage
Client entry points:
client.labels # alias: client.label
client.label_types # aliases: client.label_type, client.labeltypes, client.labeltype
See also examples/using_labels.py for a full smoke-test flow.
Creating and modifying label types
Create (POST /label_types). Required body fields: name, color, applicable_record_types. Optional: access_level (all_companies or specific_companies), allowed_company_ids (when scoped to specific companies).
priority = client.label_types.create({
"name": "Priority",
"color": "#6136ff",
"applicable_record_types": ["Article", "Asset"],
})
# kwargs style also works
status = client.label_types.create(
name="Status",
color="#00aa00",
applicable_record_types=["Article"],
)
applicable_record_types is validated locally against LABELABLE_TYPES before the request is sent.
Color values are normalized on create and update (parity with HuduAPI PowerShell ConvertTo-HuduLabelColor):
- Hex: optional
#, 3- or 6-digit; 8-digit#rrggbbaahas alpha stripped to#rrggbb - Names: English and multilingual aliases (
"light blue","grau","rouge", …) map to Hudu’s canonical palette
from hudu_magic import convert_to_hudu_label_color
convert_to_hudu_label_color("light green") # -> "#90ee90"
convert_to_hudu_label_color("#6136ff80") # -> "#6136ff"
client.label_types.create(name="Tag", color="orange", applicable_record_types=["Asset"])
List / get:
types = client.label_types.list()
types = client.label_types.list(name="Priority")
one = client.label_types.get(3)
Update (PUT /label_types/{id}):
client.label_types.update(priority.id, {"color": "#ff0000", "name": "High Priority"})
priority.update({"color": "#ff0000"})
Delete a label type via the model (uses DELETE /label_types/{id}):
priority.delete()
Applying, listing, and removing labels
A label row links one label type to one record (label_type_id, labelable_type, labelable_id). These paths are equivalent; pick whichever reads best in your script.
From the labelable object (recommended for single records):
article.add_label(priority_type) # alias: assign_label
labels = article.list_labels()
typed = article.list_labels(priority_type)
article.strip_labels(priority_type) # one type
article.strip_labels() # all labels on this record
From the label type:
priority_type.assign_to(article)
priority_type.strip_from(article)
From LabelsResource (single object or HuduCollection):
client.labels.assign(article, priority_type)
client.labels.assign(articles, priority_type) # HuduCollection → HuduCollection of Label
client.labels.list_for(article)
client.labels.list_for(article, label_type_id=priority_type.id)
client.labels.strip(article, priority_type)
client.labels.strip(articles) # batch strip
Aliases on LabelsResource: add_label = assign, strip_labels = strip.
From any BaseResource (delegates to client.labels; useful when you already have client.articles in hand):
client.articles.add_label(article, priority_type)
client.articles.add_label(articles, priority_type)
client.articles.list_labels(article, priority_type)
client.articles.strip_labels(article)
client.articles.strip_labels(articles, priority_type)
Global label list (filter by record or type):
client.labels.list(labelable_type="Article", labelable_id=article.id)
client.labels.list(label_type_id=priority_type.id)
client.labels.delete(label_id) # DELETE /labels/{id}
Non-labelable objects (for example Company) raise ValueError from to_labelable_ref() before any API call.
HuduCollection batch helpers
When list_* returns a HuduCollection, you can batch label operations without a manual loop.
For list and strip on collections of 2+ labelable records, the client uses a batched strategy: one paginated GET /labels per distinct labelable_type (optionally filtered by label_type_id), then filters locally to your record ids — instead of one list request per object. types.strip_from(article) on 2+ label types similarly lists once on the record, then deletes matching rows. assign / add_label still require one create per record (no bulk apply in the API).
If your instance has a huge number of labels for a type but you only touch a few records, targeted per-object lists can still be cheaper; tune LABEL_COLLECTION_BATCH_MIN in constants.py (default 2) if needed.
Labelable object collections (for example company.list_articles()):
articles = company.list_articles()
articles.add_label(priority_type) # alias: assign_label
all_labels = articles.list_labels() # flattened across members
articles.strip_labels(priority_type)
articles.strip_labels()
Label type collections (for example client.label_types.list()):
types = client.label_types.list()
article_types = types.for_record_type("Article")
types.assign_to(article)
types.strip_from(article)
Label collections (for example client.labels.list(...)):
labels = client.labels.list(labelable_type="Article", labelable_id=article.id)
labels.delete_all()
Others
there are many other handy and helpful class methods and many more that are planned. Whenever possible, I'll update this section with specific examples.
Creating Objects
The create base method for all objects is simple. you can specify properties in either the payload object (standard dictionary) or as kwargs (just propertyname=value)
This means you can use either:
kwargs (recommended)
client.assets.create(name="Router", company_id=1, asset_layout_id=10)
dict payload
client.assets.create(payload={"name": "Router", "company_id": 1, "asset_layout_id": 10})
Updating Objects
asset.name = "New Name"
asset.save()
or
asset.update(name="New Name")
Relations
asset.relate_to(website)
or
client.relations.create(from_obj=asset, to_obj=website)
Uploads
asset.upload_to("file.zip")
uploads = asset.list_uploads()
Photos
asset.add_photo("image.png")
photos = asset.list_photos()
Labels (quick reference)
| Goal | Example |
|---|---|
| Create label type | client.label_types.create({...}) |
| Update label type | client.label_types.update(id, {...}) |
| Apply to one record | record.add_label(label_type) |
| Apply to many records | client.labels.assign(records, label_type) |
| List on one record | record.list_labels() |
| Strip from one record | record.strip_labels(label_type) |
| Strip from many records | client.labels.strip(records, label_type) |
| Batch on a collection | records.add_label(label_type) |
Generating builds for new Hudu versions or previous versions
-
Place openapi spec file https://yoururl.huducloud.com/api-docs.json in project directory as hudu-openapiv1.json
-
run
python generate_endpoints.pyafter sourcing virtual environment (that has dev dependencies installed) -
run
./build.sh
todo: .\build.ps1
this is designed to be super simple so that subsequent releases can eventually just be automatically generated, tested, validated, and pushed to pypi.
Note on building and tests
- Run tests with
./build.sh --test(orpytestfrom a dev environment withpip install -e ".[dev]"). - Integration tests are skipped unless you set
HUDU_RUN_INTEGRATION=1. With that set, copytestenv.exampletotestenvand fill inHUDU_TEST_API_KEYandHUDU_TEST_INSTANCE.
Error Handling, Additional Info / Help
If more information is needed, you can call this method on class members to get all associated info from hudu's API spec-
huduobject.help()
For resources such as client.assets, you can call:
client.assets.describe()
or for more verbose info:
client.assets.help()
if an object type or resource doesnt support a method call or payload param, you'll be notified of which one(s), if any, are invalid.
Rate limiting (Rack::Attack)
All API traffic goes through HuduClient._send_request with retry behavior aligned to HuduAPI PowerShell Invoke-HuduRequest:
- 429 / "Retry later" / "Too Many Requests" → sleep until the next 5-minute window (plus 1–4s jitter), then retry
- Other errors (except 404) → sleep 5s, then retry once (only when
retry_on_error=True) - 404 → no retry (fail immediately)
Defaults: max_retries=1, retry_on_rate_limit=True, retry_on_error=False (rate-limit retries only). Enable generic error retry for PowerShell-style behavior:
client = HuduClient(
api_key="...",
instance_url="https://yourinstance.hudu.app",
max_retries=1,
retry_on_rate_limit=True,
retry_on_error=True,
error_retry_delay=5.0,
rate_limit_window_seconds=300,
)
Advanced Use Possibilities
Multi-Client
You can instantiate two or more client objects, like above, to transfer data from, say, your dev instance to production. This hasn't been extensively tested expecially for objects dependent on companies (assets, passwordfolders)
client2.assets.create(
**client1.assets.get(6).to_dict()
)
Philosophy
- Simple > clever
- Explicit > implicit
- Thin wrapper over Hudu API
License
MIT
Versioning convention
PyPI releases use a library SemVer prefix and a numeric suffix derived from the Hudu OpenAPI spec used to generate HuduEndpoint and related code:
MAJOR.MINOR.HUDUSPECVERSION
-
MAJOR/MINOR— reserved for this Python package (breaking API changes, larger feature sets, and so on). -
HUDUSPECVERSION— encodes the spec’s(major, minor, patch)as a single integer:hudu_spec_major * 1000 + hudu_spec_minor * 10 + hudu_spec_patchExample: OpenAPI 2.41.0 →
2 * 1000 + 41 * 10 + 0= 2410 → package segment 0.1.2410 (with0.1as the current library prefix).
When Hudu publishes a new spec, regenerate and bump HUDUSPECVERSION accordingly. For Python-only fixes (same spec, no regeneration), prefer a PEP 440 suffix such as 0.1.2410.post1 so the encoded spec stays honest.
Spec used for the current release: Hudu OpenAPI 2.44.1. The canonical package version is in pyproject.toml.
History
-
v0.1.2410 - Apr 6, 2026; Initial Release
-
v0.2.2410 - Apr 7, 2026; added validation, differentiation for procedure-vs-run and task-vs-runtask, as well as some helpful class methods.
-
v0.3.2410 - Apr 21, 2026; Procedures
POST/PUTsend a flat JSON body (noprocedurewrapper), Paginated lists always returnHuduCollection(removed previous single-pagelen/iteration quirks); acceptprocesseslist key on GET; addProcedure.add_task. README Re-aligned with process/run task rules;Procedure.save/update/deleteusePROCEDURES_IDand allowed PATCH fields;PROCEDURE_TASK_RUN_ONLY_FIELDSno longer lists removeduser_idupdate key.BaseResource.create/update: optionalpayload(kwargs-only body fields supported);validate/allow_unknown_fieldsare not merged into JSON. -
v0.4.2410.post1 - Added better support for exports, aliased create methods for exports to
new()andstart(). Added kind defaults to these and extended resource fromBaseFileResourceto allow for downloading. Lastly, added blocking method that until an export is ready for download. [PEP440 suffix noted for tag adjustment.] -
v0.4.2411 - Generated Endpoints.py from new 2.41.1 spec, which is actually no different than previous release. For consistency and clarity, pushing new release tag, Fri, April 24th, 2026
-
v0.4.2412 - Generated Endpoints.py from 2.41.2 spec, Tues, April 28, 2026
-
v0.5.2412 - Including some internally-developed helpers / sane defaults for asset layouts and fields. Such helpers facilitate creating new layouts or moving layouts (and objects referenced by fields) more easily.
FIELD_TYPES,ASSET_LAYOUT_FIELD_READ_ONLY_KEYS,ASSET_LAYOUT_POST_BODY_KEYSare for validation.normalize_layout_for_createfacilitates isomorphism for entire layouts (as huduobject-layout or layout from dictionary). Furthermore, added some very basic and specific field validation for website fields and number fields, specifically. -
v0.5.2420 - Generated Endpoints.py from 2.42.0 spec, Thurs, May 14, 2026
-
v0.5.2421 - Generated Endpoints.py from 2.42.1 hotfix, Thurs, May 20, 2026
-
v0.5.2430 - Generated Endpoints.py from 2.43.0 definitions, Wed, May 27, 2026
-
v0.5.2431 - Generated Endpoints.py from 2.43.1 definitions, Version incremented for clarity and consistency Mon, Jun 1, 2026
-
v0.5.2432 - Generated Endpoints.py from 2.43.2 definitions, Version incremented for clarity and consistency Mon, Jun 15, 2026
-
v0.6.2440 - Generated Endpoints from Hudu OpenAPI 2.44.0;
LabelsResource/LabelTypesResource; label helpers onHuduObject,BaseResource, andHuduCollection(add_label,list_labels,strip_labels,assign_to,strip_from,for_record_type,delete_all); client aliaseslabel,label_type,labeltypes; see Labels and label types above andexamples/using_labels.py. This has not been released (beta-spec) to maintain version-parity with Mainline Hudu. -
v0.7.2440 - Ensuring Rack-Attack-Standard ratelimiting procedure, introduced with http helper that waits until next 5m window if exceeded.
-
v0.8.2441 - Regenerated Endpoints from Hudu OpenAPI 2.44.1. Spec delta is Relations-only (not labels):
GET /relationsquery filters:fromable_type,fromable_id,toable_type,toable_id,is_inverse,description,created_at,updated_at(plus pagination).POST /relationscreate body now documents required fields (fromable_type,fromable_id,toable_type,toable_id) and enums that include IPAM/network types (Network,IpAddress,Vlan,VlanZone,RackStorage) alongside Asset/Company/Article/etc.- Operation IDs renamed (
create_relation,delete_relation) — cosmetic for this client. FROMABLE_TOABLE_TYPES/RelationsResource.create/relate_toalready matched.list_relationsnow uses the new server-sidefromable_*/toable_*filters (two targeted GETs + dedupe) instead of listing all relations then filtering client-side.
-
v0.8.2442 - Regenerated Endpoints from Hudu OpenAPI 2.44.2 [no change to api spec].
-
v0.8.2443 - Regenerated Endpoints from Hudu OpenAPI 2.44.3 [no change to api spec].
-
v0.8.2450 - Generated Endpoints from Hudu OpenAPI 2.45.0 - No functional changes, though some changes to verbiage / description and therefore, generated tooltips for logs, specifically.
-
v0.8.2451 - Regenerated Endpoints from Hudu OpenAPI 2.45.1 [no change to api spec].
Community & Socials
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hudu_magic-0.8.2451.tar.gz.
File metadata
- Download URL: hudu_magic-0.8.2451.tar.gz
- Upload date:
- Size: 74.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c582bbf6851fb028704e639e9aebbcd972d1f33a2ac125c7462de270ae3912e4
|
|
| MD5 |
a67d22e8d4f9dd2b71aa0c43eb93536e
|
|
| BLAKE2b-256 |
ac174ce0696202092fbed2f625fa6673c24375c6fa0d3284780edc5c441661c3
|
Provenance
The following attestation bundles were made for hudu_magic-0.8.2451.tar.gz:
Publisher:
publish-pypi.yml on Hudu-Technologies-Inc/hudu-magic
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hudu_magic-0.8.2451.tar.gz -
Subject digest:
c582bbf6851fb028704e639e9aebbcd972d1f33a2ac125c7462de270ae3912e4 - Sigstore transparency entry: 2713209112
- Sigstore integration time:
-
Permalink:
Hudu-Technologies-Inc/hudu-magic@ae778398764bebdf18eba259f43c3999af15597a -
Branch / Tag:
refs/tags/0.8.2451 - Owner: https://github.com/Hudu-Technologies-Inc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@ae778398764bebdf18eba259f43c3999af15597a -
Trigger Event:
release
-
Statement type:
File details
Details for the file hudu_magic-0.8.2451-py3-none-any.whl.
File metadata
- Download URL: hudu_magic-0.8.2451-py3-none-any.whl
- Upload date:
- Size: 69.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7e9da8366ebb05081d68c3edb3fd54daebbec6c788d81bfbd516fdf31f3bb0da
|
|
| MD5 |
08e087201a72a2e4786dc7f7224d4318
|
|
| BLAKE2b-256 |
8538b43072eadd10a843b049890733a3e662f0af3ada90d25a36a818bf964405
|
Provenance
The following attestation bundles were made for hudu_magic-0.8.2451-py3-none-any.whl:
Publisher:
publish-pypi.yml on Hudu-Technologies-Inc/hudu-magic
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hudu_magic-0.8.2451-py3-none-any.whl -
Subject digest:
7e9da8366ebb05081d68c3edb3fd54daebbec6c788d81bfbd516fdf31f3bb0da - Sigstore transparency entry: 2713209131
- Sigstore integration time:
-
Permalink:
Hudu-Technologies-Inc/hudu-magic@ae778398764bebdf18eba259f43c3999af15597a -
Branch / Tag:
refs/tags/0.8.2451 - Owner: https://github.com/Hudu-Technologies-Inc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@ae778398764bebdf18eba259f43c3999af15597a -
Trigger Event:
release
-
Statement type: