SoftLayer_Virtual_Guest setTransientWebhook - ibm-cloud

I'm looking for a sample code using SoftLayer_Virtual_Guest::setTransientWebhook for Transient VSI. Is there a sample code?
Thanks
Behzad

Try with next requests:
Method GET
http://api.softlayer.com/rest/v3.1/SoftLayer_Account/getVirtualGuests?objectMask=mask[id,transientGuestFlag]&objectFilter={"virtualGuests":{"transientGuestFlag":{"operation": 1}}}
Data 1 means true also 0 means false, in this case, we use one with data 1
Choose the VSI id you want to set and use the following request:
Method POST
http://api.softlayer.com/rest/v3.1/SoftLayer_Virtual_Guest/111111/setTransientWebhook
Body
{"parameters":[
"https://test1.com",
"testsupport"]
}
The 111111 data is the VSI that we chose in the previous request.
Reference
https://sldn.softlayer.com/reference/datatypes/SoftLayer_Virtual_Guest/#transientGuestFlag
https://sldn.softlayer.com/reference/services/SoftLayer_Virtual_Guest/setTransientWebhook/
I hope it helps you

Thanks Daniel, would this be equivalent code in python: request = client['Virtual_Guest'].createObject({
'hostname': hostname,
'domain': domainname,
'startCpus': cpus,
'maxMemory': memory,
'hourlyBillingFlag': 'true',
'datacenter': {'name': 'tor01'},
'operatingSystemReferenceCode': os_code,
# 'localDiskFlag': 'false',
"supplementalCreateObjectOptions": {"flavorKeyName": "C1_1X1X25"},
'transientGuestFlag': 'true',
# 'sshKeys': [{"id":201867}]
"parameters":["https://test1.com","testsupport"].

Related

How to generate outputs from PyTransitions FSM?

I am using PyTransitions to generate a simple FSM, configuring it using a yml file.
An example could be something like this:
initial: A
states:
- A
- B
- C
transitions:
- {trigger: "AtoC", source: "A", dest: "C"}
- {trigger: "CtoB", source: "C", dest: "B"}
My question is, using the yml file, how do I write in state outputs? For example, at state A turn on LED 1, state B turn on LED2, state C turn on LED1 and 2. I can't find any documentation for it in the PyTransitions page.
My question is, using the yml file, how do I write in state outputs?
There is no dedicated output slot for states but you can use transitions to trigger certain actions when a state is entered or left.
Actions can be done in callbacks. Those actions need to be implemented in the model. If you want to do most things via configurations you can customize Machine and the used State class. For instance, you could create a custom LEDState and assign a value array called led_states to it where each value represents a LED state. The array is applied to the LEDs in the after_state_change callback of the Model that is called update_leds:
from transitions import Machine, State
class LEDState(State):
ALL_OFF = [False] * 2 # number of LEDs
def __init__(self, name, on_enter=None, on_exit=None,
ignore_invalid_triggers=None, led_states=None):
# call the base class constructor without 'led_states'...
super().__init__(name, on_enter, on_exit, ignore_invalid_triggers)
# ... and assign its value to a custom property
# when 'led_states' is not passed, we assign the default
# setting 'ALL_OFF'
self.led_states = led_states if led_states is not None else self.ALL_OFF
# create a custom machine that uses 'LEDState'
# 'LEDMachine' will pass all parameters in the configuration
# dictionary to the constructor of 'LEDState'.
class LEDMachine(Machine):
state_cls = LEDState
class LEDModel:
def __init__(self, config):
self.machine = LEDMachine(model=self, **config, after_state_change='update_leds')
def update_leds(self):
print(f"---New State {self.state}---")
for idx, led in enumerate(self.machine.get_state(self.state).led_states):
print(f"Set LED {idx} {'ON' if led else 'OFF'}.")
# using a dictionary here instead of YAML
# but the process is the same
config = {
'name': 'LEDModel',
'initial': 'Off',
'states': [
{'name': 'Off'},
{'name': 'A', 'led_states': [True, False]},
{'name': 'B', 'led_states': [False, True]},
{'name': 'C', 'led_states': [True, True]}
]
}
model = LEDModel(config)
model.to_A()
# ---New State A---
# Set LED 0 ON.
# Set LED 1 OFF.
model.to_C()
# ---New State C---
# Set LED 0 ON.
# Set LED 1 ON.
This is just one way how this could be done. You could also just pass an array with indexes representing all LEDs that should be ON. We'd switch off all LEDs when exiting a state with before_state_change
ALL_OFF = []
# ...
self.machine = LEDMachine(model=self, **config, before_state_change='reset_leds', after_state_change='set_lets')
# ...
def reset_leds(self):
for led_idx in range(num_leds):
print(f"Set {led_idx} 'OFF'.")
def set_lets(self):
for led_idx in self.machine.get_state(self.state).led_states:
print(f"Set LED {led_idx} 'ON'.")
# ...
{'name': 'A', 'led_states': [0]},
{'name': 'B', 'led_states': [1]},
{'name': 'C', 'led_states': [0, 1]}

Openapi3 and CSV response (for Dredd)

I test my Api with DREDD against it's specification (written in Openapi3 considering, painfull limitations of Support by Dredd considered). No I have one endpoint, which produces CSV-data if the Accept-header is set so.
'/my-endpoint':
summary: ...
description: ...
get:
# parameters:
# -
# in: header
# name: Accept
# description: "Response format: application/json or text/csv"
# example: "text/csv"
responses:
'200':
description: ...
content:
text/csv:
schema:
type: string
example:
summary: 'csv table'
value: 'cell1, cell2'
When I run the test with Dredd the test fails with
expected:
headers:
body:
[
{
"key": "summary",
"value": "csv table"
},
{
"key": "value",
"value": "cell1, cell2"
}
]
statusCode: 200
Clearly there is something misunderstood and Dredd expects still JSON. Also the API is not told to produce the CSV Version. If I commit in the Accept header in the code abvoe I get the very same result - the expecetd result above and as actual result the JSON version of the my-endpoint-data and also ad warning:
warn: API description parser warning in .../tmp/transformed.specs.yml: 'Parameter Object' 'name' in location 'header' should not be 'Accept', 'Content-Type' or 'Authorization'
I read here and here: Header parameters named Accept, Content-Type and Authorization are not allowed. To describe these headers, use the corresponding OpenAPI keywords - but what are they? According to this and this page it seems to be enough to specify a response of the given type but that is clearly not enough to tell Dredd to produce such a header.
You got an error because the value of the example key is meant to be a literal example value. So in your case it's treated as an object with the summary and value properties.
Change your definition to:
content:
text/csv:
schema:
type: string
example: 'cell1, cell2'
Or if you want to provide a summary/description for an example, use examples instead:
content:
text/csv:
schema:
type: string
examples:
csv table:
summary: A CSV table with 2 cells
value: 'cell1, cell2'

Extracting Client ID as a custom dimension with audience dimensions through API

I'm looking to get some answers here regarding the matter. There is no formal documentation available, would like some answers to my dilemma. Currently on analytics, I have Client ID setup as a custom dimension, session scope, I'm currently trying to match this Client ID with other dimensions via the Analytics Reporting API v4. (Reason having done so is that because in order for Client ID to be available outside of User Explorer on Analytics, one has to setup a custom dimension for this)
It's come to my attention that when I try to match Client ID, with an Audience Dimension, such as Affinity, nothing comes up. But say I do so with another dimension like PagePath + Affinity, the table exist. So I know that it is possible to pull Audience dimensions with other dimensions and it's possible for me to pull Client ID together with other dimensions. But what I'm trying to understand is why can't I pull Client ID together with Audience dimensions?
Some clarification on the matter would truly be appreciated, thanks.
For example (Can't show everything, but this is the response body of the python script)
In the case that i try to match my custom dimension (Client ID, session scope) with Affinity.
request_report = {
'viewId': VIEW_ID,
'pageSize' : 100000,
'dateRanges': [{'startDate': '2018-12-14',
'endDate': 'today'}],
'metrics': [{'expression': 'ga:users'}
],
'dimensions': [{'name': 'ga:dateHour'},
{'name':'ga:dimension1'},
{'name': 'ga:interestAffinityCategory'}
]
}
response = api_client.reports().batchGet(
body={
'reportRequests': request_report
}).execute()
Output:
ga:dateHour ga:dimension1 ga:interestAffinityCategory ga:users
Changing my dimensions, to pagePath + Affinity
request_report = {
'viewId': VIEW_ID,
'pageSize' : 100000,
'dateRanges': [{'startDate': '2018-12-14',
'endDate': 'today'}],
'metrics': [{'expression': 'ga:users'}
],
'dimensions': [{'name': 'ga:dateHour'},
{'name': 'ga:pagePath'},
{'name': 'ga:interestAffinityCategory'}
]
}
response = api_client.reports().batchGet(
body={
'reportRequests': request_report
}).execute()
Output:
ga:dateHour ga:pagePath ga:interestAffinityCategory ga:users
2018121415 homepage Business Professionals 10
2019011715 join-beta Beauty Mavens 16
2019011715 join-beta Frequently Visits Salons 21
Now say I change my combination to custom dimension + device category
request_report = {
'viewId': VIEW_ID,
'pageSize' : 100000,
'dateRanges': [{'startDate': '2018-12-14',
'endDate': 'today'}],
'metrics': [{'expression': 'ga:users'}
],
'dimensions': [{'name': 'ga:dateHour'},
{'name': 'ga:adContent'},
{'name': 'ga:deviceCategory'}
]
}
response = api_client.reports().batchGet(
body={
'reportRequests': request_report
}).execute()
Output:
ga:dateHour ga:dimension1 ga:adContent ga:deviceCategory ga:users
2018121410 10 ad1 desktop 1
2018121410 111 ad1 mobile 1
2018121410 119 ad4 mobile 1
2018121410 15 ad3 desktop 1
2018121410 157 ad3 mobile 1
In conclusion:
What I'd like to achieve is being able to pair my custom dimensions (Client ID) together with audience dimensions in order to be able to do segmentations. But first things first, if this permutation is not possible, I would like to understand as to why it's not possible? Is this a limitation from the API side? Or is this a policy thing (taking a guess here as I understand that there are identity protection policies)?
The BigQuery integration does not contain demographics/affinitys. The User Interface contains a variety of mechanisms to prevent you from isolating individual users, so in short no.

watchman: I am missing file deletions happening before subscription

I am missing deletes in watchman. Version 4.9.0, inotify.
My test code:
#!/usr/bin/env python3
import pathlib
import pywatchman
w = pywatchman.client()
w.query('watch', '/tmp/z')
clock = w.query('clock', '/tmp/z')['clock']
print(clock)
q = w.query('subscribe', '/tmp/z', 'Buffy', {'expression':["since", clock],
"fields": ["name", "exists", "oclock", "ctime_ns", "new", "mode"]})
print(q)
f = pathlib.Path('/tmp/z/xx')
f.touch()
data = w.receive()
clock = data['clock']
print()
print('Touch file:')
print(data)
print('Clock:', clock)
f.unlink()
print()
print('Delete file:')
print(w.receive())
w.close()
w = pywatchman.client(timeout=99999)
q = w.query('subscribe', '/tmp/z', 'Buffy', {'expression':["since", clock],
"fields": ["name", "exists", "oclock", "ctime_ns", "new", "mode"]})
print(q)
print()
print('We request changes since', clock)
print(w.receive())
w.close()
What I am seeing:
We create the file. We receive the notification of the new file and the directory change. GOOD. We take note of the "clock" of this notification.
We delete the file. We get the notification of the file deletion. GOOD. Be DO NOT get the notification of the directory change.
Just imagine now that the process crashes BEFORE it can update the internal details, but it remember the changes notified in step 1 (directory update and creation of a new file). That is, transaction 1 is processed, but the program crashes before transaction 2 is processed.
We now open a new subscription to watchman (remember, we are simulating a crash) and request changes since step 1. I am simulating a recovery, where the program reboots, notice that transaction 1 was OK (the file is present) and request more changes (it should get the deletion).
I would expect to get a file deletion but I get... NOTHING. CATASTROPHIC.
Transcript:
$ ./watchman-bug.py
c:1517109517:10868:3:23
{'clock': 'c:1517109517:10868:3:23', 'subscribe': 'Buffy', 'version': '4.9.0'}
Touch file:
{'unilateral': True, 'subscription': 'Buffy', 'root': '/tmp/z', 'files': [{'name': 'xx', 'exists': True, 'oclock': 'c:1517109517:10868:3:24', 'ctime_ns': 1517114230070245747, 'new': True, 'mode': 33188}], 'is_fresh_instance': False, 'version': '4.9.0', 'since': 'c:1517109517:10868:3:23', 'clock': 'c:1517109517:10868:3:24'}
Clock: c:1517109517:10868:3:24
Delete file:
{'unilateral': True, 'subscription': 'Buffy', 'root': '/tmp/z', 'files': [{'name': 'xx', 'exists': False, 'oclock': 'c:1517109517:10868:3:25', 'ctime_ns': 1517114230070245747, 'new': False, 'mode': 33188}], 'is_fresh_instance': False, 'version': '4.9.0', 'since': 'c:1517109517:10868:3:24', 'clock': 'c:1517109517:10868:3:25'}
{'clock': 'c:1517109517:10868:3:25', 'subscribe': 'Buffy', 'version': '4.9.0'}
We request changes since c:1517109517:10868:3:24
The process hangs expecting the deletion notification.
What am I doing wrong?.
Thanks for your time and knowledge!
The issue is that you're using a since expression term rather than informing watchman to use the since generator (the recency index).
What's the difference? You can think of this as the difference between the FROM and WHERE clauses in SQL. The expression field is similar in intent to the WHERE clause: it applies to the matched results and filters them down, but what you wanted to do is specify the FROM clause by setting the since field in the query spec. This is admittedly a subtle difference.
The solution is to remove the expression term and add the generator term like this:
q = w.query('subscribe', '/tmp/z', 'Buffy',
{"since": clock,
"fields": ["name", "exists", "oclock",
"ctime_ns", "new", "mode"]})
While we don't have really any documentation on the use of the pywatchman API, you can borrow the concepts from the slightly better documented nodejs API; here's a relevant snippet:
https://facebook.github.io/watchman/docs/nodejs.html#subscribing-only-to-changed-files

how to translate curl to elixir httpoison

I have an example curl command from an api:
curl -sd '{"inputs":[{"addresses": ["add42af7dd58b27e1e6ca5c4fdc01214b52d382f"]}],"outputs":[{"addresses": ["884bae20ee442a1d53a1d44b1067af42f896e541"], "value": 4200000000000000}]}' https://api.blockcypher.com/v1/eth/main/txs/new?token=YOURTOKEN
I have no idea how to translate this into HTTPoison for Elixir. I've been trying for hours. I can't even begin to mention all the iterations I've gone through, but here's where I'm at now:
Connect.post( "https://api.blockcypher.com/v1/eth/main/txs/new?token=#{#token}",
"",
[
{ "inputs", "{addresses, #{address_from}}"},
{ "outputs", "[{addresses, #{address_to}}, {value, #{eth_amount}}]"}
]
)
unlike most everything I've tried before this actually gets to their servers and gives a response:
"{\"error\": \"Couldn't deserialize request: EOF\"}"
%{"error" => "Couldn't deserialize request: EOF"}
** (FunctionClauseError) no function clause matching in Base.encode16/2
(elixir) lib/base.ex:175: Base.encode16(nil, [])
(blockcypher) lib/blockcypher/handler.ex:55: Blockcypher.Handler.post_transa
ction_new/4
iex(46)>
can you help me out? I tried putting the data in the body portion instead of the headers but with no luck.
The data should be the second argument to HTTPoison.post/2 and should be encoded to JSON. Your data is also in the wrong format.
This should work:
Connect.post(
"https://api.blockcypher.com/v1/eth/main/txs/new?token=#{#token}",
"",
Poison.encode!(
%{"inputs" => [%{"addresses" => [address_from]}],
"outputs" => [%{"addresses" => [address_to],
"value" => eth_amount}]})
)