python3 nested dictionary unpack for format string - python-3.x

I am trying to pass a dictionary (loaded from JSON file) to format string. While single key-value unpack works correctly, I am not sure how I can access the nested keys (children) with a format string.
Or is there any other better way to pass JSON to string format?
config = {
"TEST": "TEST",
"TEST1": "TEST1",
"TEST2": {
"TEST21": "TEST21"
}
}
query_1 = """
{TEST} {TEST1}
"""
query_2 = """
{TEST} {TEST1}
{TEST2.TEST21}
"""
print(query_1.format( **config )) # WORKING
print(query_2.format( **config )) # NOT WORKING

Using f-string
config = {
"TEST": "TEST",
"TEST1": "TEST1",
"TEST2": {
"TEST21": "TEST21"
}
}
query_2 = f"""
{config['TEST']} {config['TEST1']}
{config['TEST2']['TEST21']}
"""
print(query_2)
Note, if query is sql query, there is probably better way to do what you do, not using string formatting

In your query_2 change {TEST2.TEST21} to {TEST2[TEST21]} it will work.
Ex.
query_2 = """
{TEST} {TEST1}
{TEST2[TEST21]}
"""
print(query_2.format(**config))
Output
TEST TEST1
TEST21

Related

convert string output of for loop into a single array in Groovy

I need to take my output from the for loop below and add it to a single array. The list object can either be ["envName-inactive-1", "active-1", "inactive-1", "envName-active-1"] or ["envName-inactive-2", "", "", "envName-active-2"]
My code:
if (appendVersion) {
for (elements in list) {
test = (elements + "-" + branch)
println(test)
}
} else {
println(list)
}
output:
envName-inactive-1-v2
active-1-v2
inactive-1-v2
envName-active-1-v2
and
envName-inactive-2-v2
-v2
-v2
envName-active-2-v2
desired output:
["envName-inactive-1-v2", "active-1-v2", "inactive-1-v2", "envName-active-1-v2"]
and
["envName-inactive-2-v2", "", "", "envName-active-2-v2"]
You desired format seems to be json. In Jenkins you have option to use writeJSON to convert list to json format.
def branch = "v2"
def list = ["envName-inactive-1", "active-1", "inactive-1", "envName-active-1"]
def versionedList = list.collect{it ? it+'-'+branch : ''}
def json = writeJSON returnText: true, json: versionedList
println json
the same in plain groovy:
def branch = "v2"
def list = ["envName-inactive-1", "active-1", "inactive-1", "envName-active-1"]
def versionedList = list.collect{it ? it+'-'+branch : ''}
def json = new groovy.json.JsonBuilder(versionedList).toString()
println json
result:
["envName-inactive-1-v2","active-1-v2","inactive-1-v2","envName-active-1-v2"]

groovy to get the json key values to a string

I have a json file with values - {"testID":"smoke_01","testID":"smoke_02","testID":"smoke_04"}.
I read the values for testID and saved to array. Now I was trying to make it as a simple string like -
testcase = smoke_01,smoke_02,smoke_02. My code is below :
def props = readJSON file: 'input.json'
def list = []
props.each { key, value ->
list.push("$value")
}
echo "$list"
def asString = list.join(", ")
def testcase = asString.join(", ")
But when i print testcase - its printing as [smoke_01, smoke_02, smoke_04] . Please help me to understand where I am wrong.
Assuming you really have this invalid strange JSON (keys must be unique in an Object in basically every language you parse to, but yours are not), and that readJSON actually parses your custom JSON into something you can iterate over as if it were a Map... then, this should do what you want:
def props = readJSON file: 'input.json'
def testCase = props.values().join(', ')
println testCase
Assuming you use proper JSON
By proper JSON I mean something that does not break JSON semantics, hence can be parsed by any JSON parser, not your custom one.
You JSON file should look more like this:
{ "tests": [
{ "testID": "smoke_01" },
{ "testID": "smoke_02" },
{ "testID": "smoke_03" }
] }
In which case you would parse it with:
def json = new JsonSlurper().parse(new File('input.json'))
def testCase = json.tests.collect { it.testID }.join(', ')
println testCase
There are other ways to represent this in JSON, but you should study how JSON works and what suits you best depending on how it is going to be used.
Here's the JSON spec which is simple enough you can learn it in 20 minutes:
https://www.json.org/json-en.html

why flask graphene return wrong id?

when i print the id before returning, the code print the right value ( same with id in mongo ).
but the client received a deferent id.
my query code :
def resolve_account(root, info, **kwargs):
email = kwargs.get('email', None)
password = kwargs.get('password', None)
accounts = AccountModel.objects(email=email, password=password)
if accounts.first() is None:
return ResponseMessageField(is_success=False, message="Not found")
print(accounts[0].id)
return AccountResults(accounts=[AccountField(id=account.id,
name=account.name)
for account in accounts])
console printed : `5e5f28a41e92b7cdb5cf30ea'
but my client received :
{
"data": {
"accountLogin": {
"accounts": [
{
"name": "test1",
"id": "QWNjb3VudEZpZWxkOjVlNWYyOGE0MWU5MmI3Y2RiNWNmMzBlYQ=="
}
]
}
}
}
python 3.6.9
mongoengine 0.1.9
graphene 2.1.8
graphene_mongo 0.1.1
flask 1.1.1
This is acutally an adavantage of graphene-django, if you're using auto-increment ID's.
Anyway it encodes them using base64 encoding, to get the real value, you can do
this in vanilla JS:
>> atob('QWNjb3VudEZpZWxkOjVlNWYyOGE0MWU5MmI3Y2RiNWNmMzBlYQ==')
>> "AccountField:5e5f28a41e92b7cdb5cf30ea"
So if you want to mutate something, and you have the ID, which is not bas64 encoded, what you'll have to do is:
>> btoa("AccountField:5e5f28a41e92b7cdb5cf30ea")
>> "QWNjb3VudEZpZWxkOjVlNWYyOGE0MWU5MmI3Y2RiNWNmMzBlYQ=="
In python, graphene provides an import, to_global_id and from_global_id to convert to and fro b/w base64 encoded values and the real IDs.

SQL DDL to parse JSON schema file

Can a SQL DDL statement be parsed to a simple JSON schema file as shown below without using any tools, only Scala/Python/shell scripting?
CREATE TABLE TEMP (
ID INT,
NAME STRING)
[
{
"tableName": "temp",
"columns": [
{
"columnname": "id",
"datatype": "int"
},
{
"columnname": "name",
"datatype": "string"
}
]
}
]
You can create a string in the JSON form from your DDL using the below logic (Scala code). Once the string is made, it is converted into a Dataframe. This Dataframe is then saved into an HDFS/Amazon S3 as JSON file using Dataframe's built in API called write.json
import org.apache.spark.sql.types._
import spark.implicits._
val createSql = "CREATE TABLE TEMP (ID INT, NAME STRING)"
var jsonString = """[{"tableName":"""" + createSql.split(" ")(2).toLowerCase + "\"," + "\"columns\":["
createSql.split(s"\\(")(1).split(s"\\)")(0).split(",").map(r => {
jsonString += "{" + "\"columnname\": " + "\"" + r.trim.split(" ")(0).toLowerCase + "\"," + "\"datatype\": " + "\"" + r.trim.split(" ")(1).toLowerCase + "\"},"
})
jsonString = jsonString.patch(jsonString.lastIndexOf(','), "", 1) + "]}]"
val schema: StructType = null
val reader = spark.read
Option(schema).foreach(reader.schema)
val df = reader.json(sc.parallelize(Array(jsonString)))
df.coalesce(1).write.json("<targetlocation>")
Please let me know if you have any questions.
With some matching as e.g described here: How to pattern match using regular expression in Scala? the code for this could look like the below, assuming your initial expression is passed in as sequence of lines (note that JSONObject as used below is deprecated, so replace this with some alternative).
object Parser {
implicit class Regex(sc: StringContext) {
def r = new util.matching.Regex(sc.parts.mkString, sc.parts.tail.map(_ => "x"): _*)
}
def toJson(tablename: String, columns: Seq[(String,String)]): String = {
val columnList: List[JSONObject] = columns.toStream.map(x => JSONObject(Map("columnname" -> x._1, "datatype" -> x._2))).toList
JSONArray(List(JSONObject(Map("tableName" -> tablename, "columns" -> JSONArray(columnList))))).toString()
}
def parse(lines: Seq[String]): (String, Seq[(String,String)]) = {
lines.mkString("").toLowerCase match {
case r"create\s+table\s+(\S+)${tablename}\s+\((.+)${columns}\).*" =>
val columnWithType: immutable.Seq[(String, String)] = columns.split(",").toStream
.map(x => x.split("\\s+"))
.map(x => (x.head.toLowerCase, x(1).toLowerCase))
(tablename, columnWithType)
case _ => ("",Seq.empty)
}
}
}
To test that with your test string:
val data: (String, Seq[(String, String)]) = Parser.parse(Seq("CREATE TABLE TEMP (", "ID INT,", "NAME STRING)"))
println(Parser.toJson(data._1, data._2))
With scala.util.parsing.combinator package, u could define your Lexer and Grammer parser with DDL like this,
import scala.util.parsing.combinator._
class JSON extends JavaTokenParsers {
def value: Parser[Any] = obj | arr | stringLiteral | floatingPointNumber | "null" | "true" | "false"
def obj: Parser[Any] = "{"~repsep(member, ",")~"}"
def arr: Parser[Any] = "["~repsep(value, ",")~"]"
def member: Parser[Any] = stringLiteral~":"~value
}
Above code would be used to parse JSON string into a lexel stream for further procession. Read the doc u will be able to define your SQL DDL parser.
We just published this package in https://github.com/deepstartup/jsonutils. May be you will find it useful. If you need us to update something, open up a JIRA.
Try:
pip install DDLJ
from DDLj import genddl
genddl(*param1,param2,*param3,*param4)
Where
param1= JSON Schema File
param2=Database (Default Oracle)
Param3= Glossary file
Param4= DDL output script

Assert response starts with

I am trying to assert the response, to check if the response value starts with a certain text. I tried using the function startsWith but it seems like it does not work in SOPAUI script assertion.
This is what I have tried:
import groovy.json.JsonSlurper
//grab the response
def ResponseMessage = messageExchange.response.responseContent.records
//define a JsonSlurper
def jsonSlurper = new JsonSlurper().parseText(ResponseMessage)
//log.info jsonSlurper
assert jsonSlurper.startsWith("Text")
Here is the json response
{
"Name": "Natalie",
"message": "What are you doing"
}
I want to check if the Name starts with "Nat"
From documentation JsonSlurper().parseText(String text) returns:
data structure of lists and maps
so you can not use startsWith directly. To achieve what you want you have to go to the desired object in the path and use startsWith there. Something like must works for your case:
import groovy.json.JsonSlurper
def jsonStr = '{ "Name": "Natalie", "message": "What are you doing" }'
def jsonSlurper = new JsonSlurper().parseText(jsonStr)
assert jsonSlurper.Name.startsWith("Nat")

Resources