howto pass json to docker solc - python

I used to compile my solidity contracts with compile_standard in python, but it's getting very hard to keep up with the different compiler versions. After migrating to a new system, the new compiler won't work with older contracts.
So I figured, let's do it with docker,so I can choose my compiler version, how hard can it be, right? I tried to add a string as an argument, which would be my preferred way of working, but this doesn't work. If I try to use files, I get: FileNotFoundError: [Errno 2] No such file or directory, which makes sense, I guess, since I don't mount any paths on docker, since according to the solc docs, this is not necessary. But I can't find more information here.
So my questions are;
1 if using files, how to pass the path?
2 is it possible to pass the json as a string and get a string back as a result?
compile_json = {
"language": "Solidity",
"sources": sources,
"settings":
{
"outputSelection": {
"*": {
"*": [
"metadata", "evm.bytecode"
, "evm.bytecode.sourceMap"
]
}
}
}
}
with open('data.json', 'w') as outfile:
json.dump(compile_json, outfile)
docker_cmd = 'docker run ethereum/solc:0.6.10 --standard-json < ' + self.base_path + 'data.json --allow-paths '+ self.base_path +' < out.json'
bincode = subprocess.check_output([docker_cmd]).decode('utf-8')
edit:
docker_cmd = 'docker run ethereum/solc:0.6.0 --standard-json < ' + self.base_path + 'data.json --allow-paths '+ self.base_path +' > out.json'
try:
bincode = subprocess.check_output(docker_cmd,shell=True,stderr=subprocess.STDOUT).decode('utf-8')
except subprocess.CalledProcessError as e:
raise RuntimeError("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
I've managed to get it working through docker, but now solc complains about the json format:
{"errors":[{"component":"general","formattedMessage":"* Line 2, Column 1\n Syntax error: value, object or array expected.\n* Line 1, Column 1\n A valid JSON document must be either an array or an object value.\n","message":"* Line 2, Column 1\n Syntax error: value, object or array expected.\n* Line 1, Column 1\n A valid JSON document must be either an array or an object value.\n","severity":"error","type":"JSONError"}]}

Related

AWS Lambda: Input values needs to be concatenated with error message

The query returns the expected result, the request in this forum is regarding the customized error message. Incase of failure the exception needs to stored along with the input values.
This is my first lambda code, please let me know any additional details.
Input
{"EventID":"1246", "DataflowID": "011010"}
Lambda Code (Nodejs), this was nodejs but suggestion in python are also appreciated.
var AWS = require('aws-sdk');
var mydocumentClient = new AWS.DynamoDB.DocumentClient();
exports.handler = function (event, context, callback) {
var params = {
TableName: 'TransactionLog',
KeyConditionExpression : 'EventID = :EventID and Status = :Status',
FilterExpression : 'EventID in (:EventID) and Status in (:Status)',
ExpressionAttributeValues: {":EventID": event.WorkflowDetail.EventID,":Status": "progress"},
ProjectionExpression: "EventID,DataflowID,Status"
};
mydocumentClient.scan(params, function (err, data){
if (err) {
callback(err, null);
}else{
callback(null, data);
}
}
)
}
Actual Example Error Message: Resource not found.
Expected Error Message: Resource not found "EventID":"1246", "DataflowID": "011010"
I tried using different options but no luck. please advise.
console.log(element.Title.S + " (" + element.Subtitle.S + ")");
Declare all the required events inside the parmas. I'm not sure this is the best solution but it meets my requirement. Thanks!
var params = {
...,
....,
Input: "{\"column1\" : \"" + 'type' + "\", \"column2\" : \"" + 'time' +\"}"
};
console.log(params.Input, err);
useful thread: Can execute a step function from a lambda but when I try to pass a value it fails saying input {}

How can i run a php function in python?

for some reasons, i have to run a php function in python.
However, i realized that it's beyond my limit.
So, i'm asking for help here.
below is the code
function munja_send($mtype, $name, $phone, $msg, $callback, $contents) {
$host = "www.sendgo.co.kr";
$id = ""; // id
$pass = ""; // password
$param = "remote_id=".$id;
$param .= "&remote_pass=".$pass;
$param .= "&remote_name=".$name;
$param .= "&remote_phone=".$phone; //cellphone number
$param .= "&remote_callback=".$callback; // my cellphone number
$param .= "&remote_msg=".$msg; // message
$param .= "&remote_contents=".$contents; // image
if ($mtype == "lms") {
$path = "/Remote/RemoteMms.html";
} else {
$path = "/Remote/RemoteSms.html";
}
$fp = #fsockopen($host,80,$errno,$errstr,30);
$return = "";
if (!$fp) {
echo $errstr."(".$errno.")";
} else {
fputs($fp, "POST ".$path." HTTP/1.1\r\n");
9
fputs($fp, "Host: ".$host."\r\n");
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-length: ".strlen($param)."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $param."\r\n\r\n");
while(!feof($fp)) $return .= fgets($fp,4096);
}
fclose ($fp);
$_temp_array = explode("\r\n\r\n", $return);
$_temp_array2 = explode("\r\n", $_temp_array[1]);
if (sizeof($_temp_array2) > 1) {
$return_string = $_temp_array2[1];
} else {
$return_string = $_temp_array2[0];
}
return $return_string;
}
i would be glad if anyone can show me a way.
thank you.
I don't know PHP, but based on my understanding, here should be a raw line-for-line translation of the code you provided, from PHP to python. I've preserved your existing comments, and added new ones for clarification in places where I was unsure or where you might want to change.
It should be pretty straightforward to follow - the difference is mostly in syntax (e.g. + for concatenation instead of .), and in converting str to bytes and vice versa.
import socket
def munja_send(mtype, name, phone, msg, callback, contents):
host = "www.sendgo.co.kr"
remote_id = "" # id (changed the variable name, since `id` is also a builtin function)
password = "" # password (`pass` is a reserved keyword in python)
param = "remote_id=" + remote_id
param += "&remote_pass=" + password
param += "&remote_name=" + name
param += "&remote_phone=" + phone # cellphone number
param += "&remote_callback=" + callback # my cellphone number
param += "&remote_msg=" + msg # message
param += "&remote_contents=" + contents # image
if mtype == "lms"
path = "/Remote/RemoteMms.html"
else:
path = "/Remote/RemoteSms.html"
socket.settimeout(30)
# change these parameters as necessary for your desired outcome
fp = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
errno = fp.connect_ex((host, 80))
if errno != 0:
# I'm not sure where errmsg comes from in php or how to get it in python
# errno should be the same, though, as it refers to the same system call error code
print("Error(" + errno + ")")
else:
returnstr = b""
fp.send("POST " + path + "HTTP/1.1\r\n")
fp.send("Host: " + host + "\r\n")
fp.send("Content-type: application/x-www-form-urlencoded\r\n")
# for accuracy, we convert param to bytes using utf-8 encoding
# before checking its length. Change the encoding as necessary for accuracy
fp.send("Content-length: " + str(len(bytes(param, 'utf-8'))) + "\r\n")
fp.send("Connection: close\r\n\r\n")
fp.send(param + "\r\n\r\n")
while (data := fp.recv(4096)):
# fp.recv() should return an empty string if eof has been hit
returnstr += data
fp.close()
_temp_array = returnstr.split(b'\r\n\r\n')
_temp_array2 = _temp_array[1].split(b'\r\n')
if len(temp_array2) > 1:
return_string = _temp_array2[1]
else:
return_string = _temp_array2[0]
# here I'm converting the raw bytes to a python string, using encoding
# utf-8 by default. Replace with your desired encoding if necessary
# or just remove the `.decode()` call if you're fine with returning a
# bytestring instead of a regular string
return return_string.decode('utf-8')
If possible, you should probably use subprocess to execute your php code directly, as other answers suggest, as straight-up translating code is often error-prone and has slightly different behavior (case in point, the lack of errmsg and probably different error handling in general, and maybe encoding issues in the above snippet). But if that's not possible, then hopefully this will help.
according to the internet, you can use subprocess and then execute the PHP script
import subprocess
# if the script don't need output.
subprocess.call("php /path/to/your/script.php")
# if you want output
proc = subprocess.Popen("php /path/to/your/script.php", shell=True, stdout=subprocess.PIPE)
script_response = proc.stdout.read()
PHP code can be executed in python using libraries subprocess or php.py based on the situation.
Please refer this answer for further details.

STDOUT json format with system command

I have the following example where I want to output a variable in the same json format with os.system (the idea is to output with a system command) but the double quotes are ignored in output.
import json
import os
import requests
PAYLOAD_CONF = {
"cluster": {
"ldap": "string",
"processes": 22
}
}
paystr = (str(PAYLOAD_CONF))
paydic = (json.dumps(PAYLOAD_CONF))
os.system("echo "+paystr+"")
os.system("echo "+paydic+"")
Output:
{cluster: {processes: 22, ldap: string}}
{cluster: {processes: 22, ldap: string}}
Can you help me in a workaround where I can output this with double quotes? It's very important to output with system command.
For cases like this, where you embed variables into a shell command you should use shlex.quote. Using this (and with minor cleanup), the code can be written as:
import json
import os
import shlex
PAYLOAD_CONF = {
"cluster": {
"ldap": "string",
"processes": 22
}
}
paydic = json.dumps(PAYLOAD_CONF)
os.system("echo " + shlex.quote(paydic))
Output:
{"cluster": {"ldap": "string", "processes": 22}}
Using subprocess
The subprocess module contains a lot of helper functions for calling external applications. These functions are generally preferrable to use than os.system for various security reasons.
If there is no hard dependency of os.system you can also use one of depending on your needs:
subprocess.call -- This will return even if the subprocess fails. If this returns a non-zero value, the process exited abnormally.
subprocess.check_call -- This will raise an exception if the process exits abnormally.
subprocess.check_output -- This will return stdout from the subprocess and raise an exception if it exits abnormally.
... The module contains many other helpful functions for interacting with subprocess which you should check out if the above don't suit your needs.
using check_output, the code becomes:
from subprocess import check_call
import json
import os
import shlex
PAYLOAD_CONF = {
"cluster": {
"ldap": "string",
"processes": 22
}
}
paydic = json.dumps(PAYLOAD_CONF)
check_call(["echo", paydic])
You're not adding quotes; you're adding an empty string to the end.
Also, echo is going to interpret the first set of double quotes as a wrapper around the argument – not as part of the string itself. In the echo command itself, you need to escape double quotes with a backslash, e.g. echo \"hello\" will output "hello", whereas echo "hello" will output hello.
In a Python string, you're going to have to escape the literal backslash in the echo command with another backslash, e.g. os.system('echo \\"hello\\"') for output "hello".
Applying this to your case and using format to make it easy:
import json
import os
import requests
PAYLOAD_CONF = {
"cluster": {
"ldap": "string",
"processes": 22
}
}
paystr = (str(PAYLOAD_CONF))
paydic = (json.dumps(PAYLOAD_CONF))
os.system('echo \\"{}\\"'.format(paystr))
os.system('echo \\"{}\\"'.format(paydic))
Output:
"{cluster: {ldap: string, processes: 22}}"
"{cluster: {ldap: string, processes: 22}}"
Your paystr variable is also unnecessary, since all objects are automatically converted to strings by print and format via their inherited or overridden __str__ methods.
EDIT:
To output the variable as it appears in Python you just need to iterate through the payload dict and render each key-value pair in a type-sensitive way.
import os
import requests
def make_payload_str(payload, nested=1):
payload_str = "{\n" + "\t" * nested
for i, k in enumerate(payload.keys()):
v = payload[k]
if type(k) is str:
payload_str += '\\"{}\\"'.format(k)
else:
payload_str += str(k)
payload_str += ": "
if type(v) is str:
payload_str += '\\"{}\\"'.format(v)
elif type(v) is dict:
payload_str += make_payload_str(v, nested=nested + 1)
else:
payload_str += str(v)
# Only add comma if not last element
if i < len(payload) - 1:
payload_str += ",\n" + "\t" * nested
else:
payload_str += "\n"
return payload_str + "\n" + "\t" * (nested - 1) + "}"
PAYLOAD_CONF = {
"cluster": {
"ldap": "string",
"processes": 22
}
}
paystr = make_payload_str(PAYLOAD_CONF)
os.system('echo "{}"'.format(paystr))
Output:
{
"cluster": {
"ldap": "string",
"processes": 22
}
}
If the payload contains a dictionary, as it does in the example you provided, the function calls itself to produce the string for that dictionary, indented the right number of tabs using the nested parameter.
If the payload is also allowed to have lists and other more complex types, you'll have to include cases that account for those, but it's just more of the same.

Pandoc: Markdown to Tex -- with using filter show error "failed to parse field blocks"

I try adapt this pandoc filter but I need use Span instead Div.
input file (myfile.md):
### MY HEADER
[File > Open]{.menu}
[\ctrl + C]{.keys}
Simply line
filter file (myfilter.py):
#!/usr/bin/env python
from pandocfilters import *
def latex(x):
return RawBlock('latex', x)
def latex_menukeys(key, value, format, meta):
if key == 'Span':
[[ident, classes, kvs], contents] = value
if classes[0] == "menu":
return([latex('\\menu{')] + contents + [latex('}')])
elif classes[0] == "keys":
return([latex('\\keys{')] + contents + [latex('}')])
if __name__ == "__main__":
toJSONFilter(latex_menukeys)
run:
pandoc myfile.md -o myfile.tex -F myfilter.py
pandoc:Error in $.blocks[1].c[0]: failed to parse field blocks: failed to parse field c: mempty
CallStack <fromHasCallStack>:
error, called at pandoc.hs:144:42 in main:Main
How I should use varyable "contents" correct?
Suppose Span is inside a paragraph. Then you would be trying to replace it with a RawBlock, which is not going to work. Maybe try using RawInline instead?

ignore provided input in python

I have python code which calls a shell script (get_list.sh) and this shell script calls one .txt file which is having the entires like :
aaf:hfhfh:notusable:type: - city_name
hhf:hgyt:usable:type: - city_name
llf:hdgt:used:type: - city_name
and when I providing the input like after running the python code :
code for providing the input :
List = str(raw_input('Enter pipe separated list : ')).upper().strip()
hhf|aaf|llf
code for getting the output :
if List:
try:
cmd = "/home/dponnura/get_list.sh -s " + "\"" + List + "\""
selfP = commands.getoutput(cmd).strip()
except OSError:
print bcolors.FAIL + "Could not invoke Pod Details Script. " + bcolors.ENDC
it shows me the output as :
hhf detils : hfhfh:notusable:type: - city_name
aaf details : hgyt:usable:type: - city_name
llf details : hdgt:used:type: - city_name
What my requirnment is, if I passes the input after execution of python code and if my enties are not present in .txt file it should show me the output as :
if I provide the input as :
hhf|aaf|llf|ggg
then for 'ggg' it should show me like :
'ggg' is wrong input
hhf detils : hfhfh:notusable:type: - city_name
aaf details : hgyt:usable:type: - city_name
llf details : hdgt:used:type: - city_name
Could you please let me know how can I do this in python or shell?
Here is this done in Python, without calling get_list.sh
import sys,re
List = str(raw_input('Enter pipe separated list : ')).strip().split('|')
for linE in open(sys.argv[1]):
for l1 in List:
m1 = re.match(l1+':(.+)',linE)
if m1:
print l1,'details :',m1.group(1)
List.remove(l1)
break
for l1 in List : print l1,'is wrong input'
Usage :
python script.py textFile.txt
Your task can ( and I think have to ) be implemented in pure Python. Below is one of possible variants of its solution using just Python, without external scripts or libraries
pipelst = str(raw_input('Enter pipe separated list : ')).split('|')
filepath = 'test.txt' # specify path to your file here
for lns in open(filepath):
split_pipe = lns.split(':', 1)
if split_pipe[0] in pipelst:
print split_pipe[0], ' details : ', split_pipe[1]
pipelst.remove(split_pipe[0])
for lns in pipelst : print lns,' is wrong input'
As you can see, it is a short, simple and clear.

Categories