Substitute values in dictionary - python

I have a python dictionary as and I want to substitute the values in it.
dict = {
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":{circle}: <{log_url}| {task}>"
}
},
{
"type": "divider"
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Dag Name:* {dag}"
},
{
"type": "mrkdwn",
"text": "*Execution Time:* {exec_time} UTC"
}
]
}
]
}
I want to substitute the values enclosed in {} such as circle, log_url and so on.
I have tried the following approach by converting it in string representation but I am getting exceptions.
dict = """
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":{circle}: <{log_url}| {task}>"
}
},
{
"type": "divider"
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Dag Name:* {dag}"
},
{
"type": "mrkdwn",
"text": "*Execution Time:* {exec_time} UTC"
}
]
}
]
}""".format(task="a",
dag="b",
exec_time="10",
log_url="url",
circle=circle)
But it it giving me errors.
ERROR - '\n\t"blocks"'
...
KeyError: '\n\t"blocks"'
How can I resolve it?
Complete code:
import json
import requests
def send_slack_success_metadata_alert():
circle = 'green-tick'
template = """{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":{circle}: <{log_url}| {task}>"
}
},
{
"type": "divider"
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Dag Name:* {dag}"
},
{
"type": "mrkdwn",
"text": "*Execution Time:* {exec_time} UTC"
}
]
}
]
}""".format(
task="T1",
dag="ID",
exec_time="10",
log_url="dummyurl",
circle=circle
)
print(template)
send_alert("http://localhost:80",template)
def send_alert(url, message):
requests.post(url=url, data=json.dumps({'text': message}),
headers={'Content-type': 'application/json'})
if __name__ == "__main__":
print(send_slack_success_metadata_alert())

do you need to set the values at a later step? Or could f-strings be the solution for you?
task="a"
dag="b"
exec_time="10"
log_url="url"
circle=circle
dict = {
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": f":{circle}: <{log_url}| {task}>"
}
},
{
"type": "divider"
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": f"*Dag Name:* {dag}"
},
{
"type": "mrkdwn",
"text": f"*Execution Time:* {exec_time} UTC"
}
]
}
]
}

Related

Sending data to Slack Hook through python

Based on Slack documentation, each new block element is a new message.
https://api.slack.com/messaging/composing/layouts
In such a case, the below example would send one message.
{
"blocks": [
{
"type": "section",
"text": {
"type": "plain_text",
"text": "This is a plain text section block.",
"emoji": true
}
}
]
}
In this case, two messages:
{
"blocks": [
{
"type": "section",
"text": {
"type": "plain_text",
"text": "This is a plain text section block.",
"emoji": true
}
},
{
"type": "section",
"text": {
"type": "plain_text",
"text": "This is a plain text section block.",
"emoji": true
}
}
]
}
My goal - is to generate such a JSON/Dictionary structure in Python, from two lists and then send it all as separate messages, as shown in the second case, but instead of two, as many elements as there are.
first = ['Tomato', 'Potato', 'Fish', 'Chicken']
second = ['tasty', 'good', 'nice', 'bad']
dictionary = {first[i]: second[i] for i in range(len(first))}
slackmessagexample = {"blocks": [
{
"type": "section",
"text": food + " " + taste
} for food, taste in dictionary.items()
]
}
jsonoutput = json.dumps(slackmessagexample, indent=2)
print(jsonoutput)
Output:
{
"blocks": [
{
"type": "section",
"text": "Tomato tasty"
},
{
"type": "section",
"text": "Potato good"
},
{
"type": "section",
"text": "Fish nice"
},
{
"type": "section",
"text": "Chicken bad"
}
]
}
This may seem silly, but I'm not able to figure out, how would one add for loop within the nested dictionary/JSON format in such case.
My final desired output should look like this:
{
"blocks": [
{
"type": "section",
"text": {
"type": "plain_text",
"text": "Tomato tasty",
"emoji": true
}
},
{
"type": "section",
"text": {
"type": "plain_text",
"text": "Potato good",
"emoji": true
}
},
{
"type": "section",
"text": {
"type": "plain_text",
"text": "Fish nice",
"emoji": true
}
},
{
"type": "section",
"text": {
"type": "plain_text",
"text": "Chicken bad",
"emoji": true
}
}
]
}
You were almost there! You can just add the nested dictionary in the comprehension. Also, I recommend using Python's zip function for your case when creating the dictionary. It creates an iterable of tuples which can be casted into dict directly.
As for your JSON structure, take a look at the following:
import json
first = ["Tomato", "Potato", "Fish", "Chicken"]
second = ["tasty", "good", "nice", "bad"]
dictionary = dict(zip(first, second))
slackmessagexample = {
"blocks": [
{
"type": "section",
"text": {"type": "plain_text", "text": food + " " + taste, "emoji": True},
}
for food, taste in dictionary.items()
]
}
jsonoutput = json.dumps(slackmessagexample, indent=2)
print(jsonoutput)
Output:
{
"blocks": [
{
"type": "section",
"text": {
"type": "plain_text",
"text": "Tomato tasty",
"emoji": true
}
},
{
"type": "section",
"text": {
"type": "plain_text",
"text": "Potato good",
"emoji": true
}
},
{
"type": "section",
"text": {
"type": "plain_text",
"text": "Fish nice",
"emoji": true
}
},
{
"type": "section",
"text": {
"type": "plain_text",
"text": "Chicken bad",
"emoji": true
}
}
]
}

A Python script that can navigate a .json and export a .csv based on a search term

I want to take a .json of "_PRESET..." items and their "code-state"s with "actions" that contain other "code-state"s, "appearance"s, and "switch"s and turn it into .csv produced from the actions under a given "_PRESET...", including the "code-state"s and the "actions" listed under their individual entries.
This would allow a user to enter the "_PRESET..." name and receive a 3-column .csv file containing each action's "type", name, and "value". There are of course ways to export the entire .json easily, but I can't fathom a way to navigate it like is needed.
enters "_PRESET_Config_A" for
input.json:
{
"abc_data": {
"_PRESET_Config_A": {
"properties": {
"category": "configuration",
"name": "_PRESET_Config_A",
"collection": null,
"description": ""
},
"actions": {
"EN-R9": {
"type": "code_state",
"value": "on"
}
}
},
"PN4FP": {
"properties": {
"category": "uncategorized",
"name": "PN4FP",
"collection": null,
"description": ""
},
"actions": {
"E_xxxxxx_Default": {
"type": "appearance",
"value": "M_Red"
}
}
},
"HEDIS": {
"properties": {
"category": "uncategorized",
"name": "HEDIS",
"collection": null,
"description": ""
},
"actions": {
"E_xxxxxx_Default": {
"type": "appearance",
"value": "M_Purple"
}
}
},
"_PRESET_Config_B": {
"properties": {
"category": "configuration",
"name": "_PRESET_Config_A",
"collection": null,
"description": ""
},
"actions": {
"HEDIS": {
"type": "code_state",
"value": "on"
}
}
},
"EN-R9": {
"properties": {
"category": "uncategorized",
"name": "EN-R9",
"collection": null,
"description": ""
},
"actions": {
"PN4FP": {
"type": "code_state",
"value": "on"
},
"switch_StorageBin": {
"type": "switch",
"value": "00_w_Storage_Bin_R9"
}
}
}
}
}
Desired output.csv
type,name,value
code_state,EN-R9,on
code_state,PN4FP,on
appearance,E_xxxxxx_Default,M_Red
switch,switch_StorageBin,00_w_Storage_Bin_R9

How to add condition to add a mandatory input field for the user in slack bot using python?

I am creating a slack bot in python using slack bolt. I have created a form like structure for the user to provide input values but I need to specify some inputs as mandatory. I tried using the "optional":true field but did not get any result
I need to give the datepicker input and multi select input as mandatory fields for the user where input is necessary.
Below is the block I have created:
blocks = [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Title"
}
},
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Date Duration"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "_Required Field_"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Start Date"
}
},
{
"type": "input",
"element": {
"type": "datepicker",
"placeholder": {
"type": "plain_text",
"text": "Select Start date"
},
"action_id": "start_date_action"
},
"label": {
"type": "plain_text",
"text": " "
},
"hint": {
"type": "plain_text",
"text": "Please ensure start date should be greater than current date "
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "End Date"
}
},
{
"type": "input",
"element": {
"type": "datepicker",
"placeholder": {
"type": "plain_text",
"text": "Select End date"
},
"action_id": "end_date_action"
},
"label": {
"type": "plain_text",
"text": " "
},
"hint": {
"type": "plain_text",
"text": "Please ensure end date should be greater than start date "
}
},
{
"type": "divider"
},
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Field1"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "_Required Field_"
}
},
{
"type": "input",
"hint": {
"type": "plain_text",
"text": "Multiple inputs are accepted"
},
"element": {
"type": "multi_static_select",
"placeholder": {
"type": "plain_text",
"text": "Select field"
},
"options": [
{
"text": {
"type": "plain_text",
"text": "11111"
},
"value": "value-0"
},
{
"text": {
"type": "plain_text",
"text": "22222"
},
"value": "value-1"
}
],
"action_id": "1_multi_select-action"
},
"label": {
"type": "plain_text",
"text": " "
}
},
{
"type": "divider"
},
{
"type": "divider"
},
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Field3"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "_Optional Field_"
}
},
{
"type": "input",
"hint": {
"type": "plain_text",
"text": "Multiple inputs are accepted"
},
"element": {
"type": "multi_static_select",
"placeholder": {
"type": "plain_text",
"text": "Select Categories"
},
"options": [
{
"text": {
"type": "plain_text",
"text": "adventure"
},
"value": "value-0"
},
{
"text": {
"type": "plain_text",
"text": "biking"
},
"value": "value-2"
}
],
"action_id": "categories_multi_select-action"
},
"label": {
"type": "plain_text",
"text": " "
}
},
{
"type": "divider"
},
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Number"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "_Optional Field_"
}
},
{
"type": "input",
"hint": {
"type": "plain_text",
"text": "Numeric values only"
},
"element": {
"type": "plain_text_input",
"action_id": "plain_text_input-action",
"placeholder": {
"type": "plain_text",
"text": "Enter Numeric Value"
}
},
"label": {
"type": "plain_text",
"text": " "
}
},
{
"type": "divider"
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Submit"
},
"value": "submit_form",
"action_id": "submit_action"
}
]
}
]
And passing the black to post a message like this
app.client.chat_postEphemeral(
channel=body["channel"]["id"],
user=body['user']['id'],
blocks=param_block,
text="text_msg",
)
Is there a way to consider text input field with just numerical values?
I'm also attaching the screenshot of the block

Is there a way to add curly brackets around a list of dictionaries already existing within a JSON file?

I currently have two JSONS that I want to merge into one singular JSON, additionally I want to add in a slight change.
Firstly, these are the two JSONS in question.
An intents JSON:
[
{
"ID": "G1",
"intent": "password_reset",
"examples": [
{
"text": "I forgot my password"
},
{
"text": "I can't log in"
},
{
"text": "I can't access the site"
},
{
"text": "My log in is failing"
},
{
"text": "I need to reset my password"
}
]
},
{
"ID": "G2",
"intent": "account_closure",
"examples": [
{
"text": "I want to close my account"
},
{
"text": "I want to terminate my account"
}
]
},
{
"ID": "G3",
"intent": "account_creation",
"examples": [
{
"text": "I want to open an account"
},
{
"text": "Create account"
}
]
},
{
"ID": "G4",
"intent": "complaint",
"examples": [
{
"text": "A member of staff was being rude"
},
{
"text": "I have a complaint"
}
]
}
]
and an entities JSON:
[
{
"ID": "K1",
"entity": "account_type",
"values": [
{
"type": "synonyms",
"value": "business",
"synonyms": [
"corporate"
]
},
{
"type": "synonyms",
"value": "personal",
"synonyms": [
"vanguard",
"student"
]
}
]
},
{
"ID": "K2",
"entity": "beverage",
"values": [
{
"type": "synonyms",
"value": "hot",
"synonyms": [
"heated",
"warm"
]
},
{
"type": "synonyms",
"value": "cold",
"synonyms": [
"ice",
"freezing"
]
}
]
}
]
The expected outcome is to create a JSON file that mimics this structure:
{
"intents": [
{
"intent": "password_reset",
"examples": [
{
"text": "I forgot my password"
},
{
"text": "I want to reset my password"
}
],
"description": "Reset a user password"
}
],
"entities": [
{
"entity": "account_type",
"values": [
{
"type": "synonyms",
"value": "business",
"synonyms": [
"company",
"corporate",
"enterprise"
]
},
{
"type": "synonyms",
"value": "personal",
"synonyms": []
}
],
"fuzzy_match": true
}
],
"metadata": {
"api_version": {
"major_version": "v2",
"minor_version": "2018-11-08"
}
},
"dialog_nodes": [
{
"type": "standard",
"title": "anything_else",
"output": {
"generic": [
{
"values": [
{
"text": "I didn't understand. You can try rephrasing."
},
{
"text": "Can you reword your statement? I'm not understanding."
},
{
"text": "I didn't get your meaning."
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"conditions": "anything_else",
"dialog_node": "Anything else",
"previous_sibling": "node_4_1655399659061",
"disambiguation_opt_out": true
},
{
"type": "event_handler",
"output": {
"generic": [
{
"title": "What type of account do you hold with us?",
"options": [
{
"label": "Personal",
"value": {
"input": {
"text": "personal"
}
}
},
{
"label": "Business",
"value": {
"input": {
"text": "business"
}
}
}
],
"response_type": "option"
}
]
},
"parent": "slot_9_1655398217028",
"event_name": "focus",
"dialog_node": "handler_6_1655398217052",
"previous_sibling": "handler_7_1655398217052"
},
{
"type": "event_handler",
"output": {},
"parent": "slot_9_1655398217028",
"context": {
"account_type": "#account_type"
},
"conditions": "#account_type",
"event_name": "input",
"dialog_node": "handler_7_1655398217052"
},
{
"type": "standard",
"title": "business_account",
"output": {
"generic": [
{
"values": [
{
"text": "We have notified your corporate security team, they will be in touch to reset your password."
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"parent": "node_3_1655397279884",
"next_step": {
"behavior": "jump_to",
"selector": "body",
"dialog_node": "node_4_1655399659061"
},
"conditions": "#account_type:business",
"dialog_node": "node_1_1655399028379",
"previous_sibling": "node_3_1655399027429"
},
{
"type": "standard",
"title": "intent_collection",
"output": {
"generic": [
{
"values": [
{
"text": "Thank you for confirming that you want to reset your password."
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"next_step": {
"behavior": "jump_to",
"selector": "body",
"dialog_node": "node_3_1655397279884"
},
"conditions": "#password_reset",
"dialog_node": "node_3_1655396920143",
"previous_sibling": "Welcome"
},
{
"type": "frame",
"title": "account_type_confirmation",
"output": {
"generic": [
{
"values": [
{
"text": "Thank you"
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"parent": "node_3_1655396920143",
"context": {},
"next_step": {
"behavior": "skip_user_input"
},
"conditions": "#password_reset",
"dialog_node": "node_3_1655397279884"
},
{
"type": "standard",
"title": "personal_account",
"output": {
"generic": [
{
"values": [
{
"text": "We have sent you an email with a password reset link."
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"parent": "node_3_1655397279884",
"next_step": {
"behavior": "jump_to",
"selector": "body",
"dialog_node": "node_4_1655399659061"
},
"conditions": "#account_type:personal",
"dialog_node": "node_3_1655399027429"
},
{
"type": "standard",
"title": "reset_confirmation",
"output": {
"generic": [
{
"values": [
{
"text": "Do you need assistance with anything else today?"
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"digress_in": "does_not_return",
"dialog_node": "node_4_1655399659061",
"previous_sibling": "node_3_1655396920143"
},
{
"type": "slot",
"output": {},
"parent": "node_3_1655397279884",
"variable": "$account_type",
"dialog_node": "slot_9_1655398217028",
"previous_sibling": "node_1_1655399028379"
},
{
"type": "standard",
"title": "welcome",
"output": {
"generic": [
{
"values": [
{
"text": "Hello. How can I help you?"
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"conditions": "welcome",
"dialog_node": "Welcome"
}
],
"counterexamples": [],
"system_settings": {
"off_topic": {
"enabled": true
},
"disambiguation": {
"prompt": "Did you mean:",
"enabled": true,
"randomize": true,
"max_suggestions": 5,
"suggestion_text_policy": "title",
"none_of_the_above_prompt": "None of the above"
},
"human_agent_assist": {
"prompt": "Did you mean:"
},
"intent_classification": {
"training_backend_version": "v2"
},
"spelling_auto_correct": true
},
"learning_opt_out": false,
"name": "Reset Password",
"language": "en",
"description": "Basic Password Reset Request"
}
So what I am missing in my original files, is essentially:
"intents":
and for the entities file:
"entities"
at the start of each list of dictionaries.
Additionally, I would need to wrap the whole thing in curly braces to comply with json formatting.
As seen, the final goal is not just appending these two to one another but the file technically continues with some other JSON code that I have yet to write and deal with.
My question now is as follows; by what method can I either add in these words and the braces to the individual files, then combine them into a singular JSON or alternatively by what method can I read in these files and combine them with the changes all in one go?
The new output file closing on a curly brace after the entities list of dicts is an acceptable outcome for me at the time, so that I can continue to make changes and hopefully further learn from this how to do these changes in future when I get there.
TIA
JSON is only a string format, you can it load in a language structure, in python that is list and dict, do what you need then dump it back, so you don't "add strings" and "add brackets", on modify the structure
file = 'intents.txt'
intents = json.load(open(file)) # load a list
file = 'entities.txt'
entities = json.load(open(file)) # load a list
# create a dict
content = {
"intents": intents,
"entities": entities
}
json.dump(content, open(file, "w"))
If you're reading all the json in as a string, you can just prepend "{'intents':" to the start and append a closing "}".
myJson = "your json string"
myWrappedJson = '{"intents":' + myJson + "}"

"object mapping [prices] can't be changed from nested to non-nested" on Bulk Python

I'm trying to insert a doc in ElasticSearch but every time i try to insert in python, its return me an error. But if i try to insert from Kibana or cUrl, its succeed.
I already tried the elasticserach-dsl but i've got the same error.
(Sorry for my bad english, i'm from brazil :D)
Error i've got:
elasticsearch.helpers.BulkIndexError: ((...)'status': 400, 'error': {'type':
'illegal_argument_exception', 'reason': "object mapping [prices] can't be changed from nested to non-nested"}}}])
My code:
from elasticsearch import Elasticsearch
from elasticsearch.helpers import bulk
doc = [{
"_index": "products",
"_type": "test_products",
"_source": {
[...]
"prices": {
"latest": {
"value": 89,
"when": 1502795602848
},
"old": [
{
"value": 0,
"when": 1502795602848
}
]
},
"sizes": [
{
"name": "P",
"available": True
},
{
"name": "M",
"available": True
}
],
"created": "2017-08-15T08:13:22.848284"
}
}]
bulk(self.es, doc, index="products")
My ES mapping:
{
"test_products": {
"mappings": {
"products": {
"properties": {
"approved": {
"type": "boolean"
},
"available": {
"type": "boolean"
},
"brand": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"buyClicks": {
"type": "integer"
},
"category": {
"type": "keyword"
},
"code": {
"type": "keyword"
},
"color": {
"type": "nested",
"properties": {
"name": {
"type": "keyword"
},
"value": {
"type": "keyword"
}
}
},
"created": {
"type": "date"
},
"description": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"gender": {
"type": "keyword"
},
"images": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"likes": {
"type": "integer"
},
"link": {
"type": "keyword"
},
"name": {
"type": "text",
"term_vector": "yes",
"analyzer": "nGram_analyzer",
"search_analyzer": "whitespace_analyzer"
},
"prices": {
"type": "nested",
"properties": {
"latest": {
"type": "nested",
"properties": {
"value": {
"type": "long"
},
"when": {
"type": "date",
"format": "dd-MM-yyyy||epoch_millis"
}
}
},
"old": {
"type": "nested",
"properties": {
"value": {
"type": "long"
},
"when": {
"type": "date",
"format": "dd-MM-yyyy||epoch_millis"
}
}
}
}
},
"redirectClicks": {
"type": "integer"
},
"sizes": {
"type": "nested",
"properties": {
"available": {
"type": "boolean"
},
"name": {
"type": "keyword"
},
"quantity": {
"type": "integer"
}
}
},
"slug": {
"type": "keyword"
},
"store": {
"type": "keyword"
},
"subCategories": {
"type": "nested",
"properties": {
"name": {
"type": "keyword"
},
"value": {
"type": "keyword"
}
}
},
"tags": {
"type": "text",
"fields": {
"raw": {
"type": "text",
"term_vector": "yes",
"analyzer": "nGram_analyzer",
"search_analyzer": "whitespace_analyzer"
}
}
},
"thumbnails": {
"type": "keyword"
}
}
}
}
}
}

Categories