REST API File Upload - Porting Python to PowerShell - python

Could anyone help me perform the following Python process in PowerShell?
json_res = json.loads(res.text,object_pairs_hook=collections.OrderedDict)
files = {'file':open(image_path,'rb').read()}
_data = json_res.items()
_data[1] = ('upload_params',_data[1][1].items())
upload_file_response = requests.post(json_res['upload_url'],data=_data[1][1],files=files,allow_redirects=False)
Here is my PowerShell to get the initial json response used in the json_res object using:
$initialization_parameters = #{
"name" = $($image.Name);
"size" = $($image.Length);
"content_type" = $(if ($image.Extension -match 'jp*g') { "image/jpeg" } elseif ($image.Extension -match 'png') { "image/png" } elseif ($image.Extension -match 'gif') { "image/gif" } else { "image/jpeg" });
"parent_folder_path" = "profile pictures";
"as_user_id" = $("sis_user_id:" + $file_id)
}
$initialization_parameters = $initialization_parameters | ConvertTo-Json
$initial_response = Invoke-RestMethod -Uri $avatars_base_url -Headers $headers -Body $initialization_parameters -ContentType "application/json" -Method POST
I am not sure how to do the next request though and add the image for upload - I have tried sending a byte array OR just the local file path, but those don't seem to work.
Specifically, I would like to know how to best mimic the 2nd and 5th lines of the Python code I have there in PowerShell.
Any help would be appreciated.

I think this is what you need to do. If not, hopefully it will at least put you on the right track...
$FileContent = [System.IO.File]::ReadAllBytes($Image.FullName)
$UploadInfo #{
"File" = $Image.Name
"Data" = [System.Convert]::ToBase64String($FileContent)
}
$FileUpload = Invoke-JSONMethod -uri $Upload_URL -ContentType "application/json" -Method POST -Body (ConvertTo-Json $UploadInfo) -AcceptType "application/json"

Related

wordpress: wp_remote_post can't pass body to the fast api, while from api docs and python requests no issue, error msg: value is not a valid dict, 422

background: I am trying to make a fastapi and wordpress plugin which will use api in localhost (both sits on the same server), i have developed the api and its working perfectly fine through swagger ui and python request library however can't use it in the plugin through wp_remote_post
code for the api:
from fastapi import FastAPI
from pydantic import BaseModel
from api.article import add_article, html_format_data
app = FastAPI()
class PostData(BaseModel):
links: list
title: str
#app.post('/create_post/')
def create_post(post_data: PostData):
html_format = html_format_data(post_data.links, post_data.title) # list of dicts
if add_article(post_data.title, html_format):
return {"status": 201, "success": True}
else:
return {"error"}
python request code:
import requests
data = {
"title": "gaming",
"links": [
{
"id": "video id 1",
"thumbnail": "url of thumbnail 1,
"title": "title of video 1"
},
{
"id": "video id 2",
"thumbnail": "url of thumbnail 2 ,
"title": "title of video 2"
}
]
}
res = requests.post('http://127.0.0.1:5000/create_post/', json=data)
print(res.content)
same success through swagger ui:
curl -X 'POST' \
'http://127.0.0.1:5000/create_post/' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"links": [
{
"id": "shortand",
"thumbnail": "shortand",
"title": "shortand"
},
{
"id": "shortand",
"thumbnail": "shortand",
"title": "shortand"
}
],
"title": "gaming"
}'
but when i do it through wordpress plugin which code is below:
function create_post( $data, $query ) {
$url = 'http://127.0.0.1:5000/create_post/';
$arguments = array(
'method' => 'POST',
'body' => json_encode(array(
"links" => $data,
"title" => $query
)),
'header' => array(
'Content-Type' => 'application/json',
'accept' => 'application/json'
)
);
$response = wp_remote_post( $url, $arguments );
// echo '<script>console.log(`data: ' . $arguments["body"] . '`)</script>';
echo '<script>console.log(`' . json_encode($response) . '`)</script>';
}
i get this error in the console:
{"headers":{},"body":"{"detail":[{"loc":["body"],"msg":"value is not a valid dict","type":"type_error.dict"}]}","response":{"code":422,"message":"Unprocessable Entity"},"cookies":[],"filename":null,"http_response":{"data":null,"headers":null,"status":null}}
i am new to wordpress and php.
i did consult these solutions but nothing seem to work as i am doing in from php.
POST request response 422 error {'detail': [{'loc': ['body'], 'msg': 'value is not a valid dict', 'type': 'type_error.dict'}]}
FastAPI - "msg": "value is not a valid dict" in schema request
EDIT
i did the below as suggested BUT still getting the same error, heres the php code:
function create_post( $data, $query ) {
$url = 'http://127.0.0.1:5000/create_post/';
$data_arr = array("links" => $data,"title" => $query);
$data_obj = (object) $data_arr;
$body = json_encode( $data_obj );
$arguments = array(
'method' => 'POST',
'body' => $body,
'header' => array(
'Content-Type' => 'application/json',
'accept' => 'application/json'
)
);
$response = wp_remote_post( $url, $arguments );
echo '<script>console.log(`' . $body . '`)</script>';
echo '<script>console.log(`' . json_encode($response) . '`)</script>';
}
SOLVED
lol my issue was a idiotic, i missed the "s" in headers so it want any json anymore because it cant see headers so it couldnt find it json thats why it was giving the error not a valid dict.
When handling JSON from php, we sometimes run into problems with the distinction between objects and associative arrays.
Try casting your body array as an object before giving it to json_encode(), something like this:
$body = json_encode( (object)
array(
"links" => $data,
"title" => $query
));
print_r ($body); //debugging: examine JSON to pass to web service
$arguments = array(
'method' => 'POST',
'body' => $body,
'header' => array(
'Content-Type' => 'application/json',
'accept' => 'application/json'
)
);
$response = wp_remote_post( $url, $arguments );

I want to generate any view of android phone as an image and also share that generated image via whatsapp, skype and mail

Here is my code can anybody suggest me what to do also NOTE: My app only supports from android 6 to 10 devices only so suggest me accordingly
private fun shareInvoice(){
binding.consLayout1.isDrawingCacheEnabled = true
binding.consLayout1.buildDrawingCache()
binding.consLayout1.drawingCacheQuality = View.DRAWING_CACHE_QUALITY_HIGH
val bitmap:Bitmap = binding.consLayout1.drawingCache
val sdf = SimpleDateFormat("dd-MM-yyyy hh:mm:ss", Locale.getDefault())
val root = Environment.getExternalStorageDirectory().absoluteFile
val file = File(root,"/Pictures")
val imageName = "ServiceInvoice_${businessName}_${sdf.format(System.currentTimeMillis())}"
val myFile = File(file,imageName)
if (myFile.exists()){
myFile.delete()
}
try {
val fos = FileOutputStream(myFile)
bitmap.compress(Bitmap.CompressFormat.JPEG,100, fos)
fos.flush()
fos.close()
showMessage("Invoice generated successfully")
binding.consLayout1.isDrawingCacheEnabled = false
Log.e("INVOICE TAG", "shareInvoice:$myFile")
}catch (e:Exception){
Log.e("FOS TAG", "shareInvoice:$e")
}
}
Follow the method
private Uri saveImageExternal(Bitmap image) {
//TODO - Should be processed in another thread
Uri uri = null;
try {
File file = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "to-share.png");
FileOutputStream stream = new FileOutputStream(file);
image.compress(Bitmap.CompressFormat.PNG, 90, stream);
stream.close();
uri = Uri.fromFile(file);
} catch (Execption e) {
Log.d(TAG, "IOException while trying to write file for sharing: " + e.getMessage());
}
return uri;
}
private void shareImageUri(Uri uri){
Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setType("image/png");
startActivity(intent);
}
So Call
Uri uri = saveImageExternal(bitmap);
shareImageUri(uri);
Don't Forget to add in manifest and Request The Permission
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18"/>
Here i get the final solution of my question if anybody wants to implement this functionality in their application
Thank you people those who posted their suggestion and interest.
This code i have tested in Android version 9,10,11 and 7
private fun scanFile(path: String) {
try {
MediaScannerConnection.scanFile(context, arrayOf(path), null) { path, uri ->
Log.d(
"Tag",
"Scan finished. You can view the image in the gallery now."
)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun shareInvoice(){
val file1 = File(
context?.getExternalFilesDir(Environment.DIRECTORY_PICTURES)?.path,
Common.APP_DIRECTORY
)
if (!file1.exists()) {
file1.mkdirs()
}
val fileName = file1.absolutePath + "/" + System.currentTimeMillis() + ".jpg"
val bitmap = binding.sectionScreenShot.getBitmapFromView()
try {
val fos = FileOutputStream(File(fileName))
bitmap?.compress(Bitmap.CompressFormat.JPEG, 100, fos)
fos.flush()
fos.close()
showMessage(getString(R.string.message_invoice_generated))
scanFile(fileName)
val uriForFile = FileProvider.getUriForFile(requireContext(),
requireContext().applicationContext.packageName + ".provider",
File(fileName))
val share `enter code here`= Intent(Intent.ACTION_SEND)
share.type = "image/jpg"
share.putExtra(Intent.EXTRA_STREAM, uriForFile)
lifecycleScope.launch {
delay(1000)
startActivity(Intent.createChooser(share, "Share Invoice"))
}
} catch (e: Exception) {
Log.e("FOS TAG", "shareInvoice:$e")
}
}

Uploading csv file in Golang through API call ( Curl Request & python request provided)

I'm new to Golang and would like to upload a csv file to a website with a client_api_key, bucket and folder. Is there a Golang solution for this? I'm creating the csv file via Golang.
This is the curl request
curl --location -- request POST 'https://drivex-service.sample.com/report/api/upload' \
-- hearder 'Cookie: '89825f9123456fa0' \
-- form 'Client_api_key=vfBM-zrfumyh9WUTKGbQ=' \
-- form 'bucket=bucket1' \
-- form 'folder=ROLE/YES/FOLDER' \
-- form 'files[]=#/D:/User/example.csv'
Here's the python post request
def drivex_upload(file_obj):
data = {
"folder": 'ROLE/YES/FOLDER',
"client_api_key": 'vfBM-zrfumyh9WUTKGbQ=',
"bucket": 'bucket1'
}
headers = {
"Accept": "application/json",
"ContentType": "multipart/form-data"
}
files = {
"files[]": file_obj
}
r = requests.post(
self.upload_url,
data=data,
files=files,
headers=headers,
verify=False,
)
if r.status_code == 200:
json_data = r.json()
return r, None
else:
return r, "error while uploading"
I tried the following in Golang (not using multiparse) but am unsure of where to put the Client_api_key, bucket and folder
file, err := os.Create(fileName)
if err != nil {
log.Fatal(err)
}
defer file.Close()
writer := csv.NewWriter(file)
defer writer.Flush()
// define column headers
// write column headers
writer.Write(headers)
for key := range m {
r := make([]string, 0, 1+len(headers))
r = append(r, m.field1,m.field2,m.field3)
writer.Write(r)
}
req, err := http.NewRequest("POST", "https://drivex-service.sample.com/report/api/upload", file)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Accept", "application/json")
Will appreciate help in constructing a working Golang POST request for this!
I think this does it:
package main
import (
"net/http"
"net/url"
"os"
)
func main() {
r, e := http.NewRequest(
"POST", "https://drivex-service.sample.com/report/api/upload", nil,
)
if e != nil {
panic(e)
}
f, e := os.ReadFile("file.csv")
if e != nil {
panic(e)
}
v := url.Values{
"Client_api_key": {"=vfBM-zrfumyh9WUTKGbQ="},
"bucket": {"bucket1"},
"files[]": {string(f)},
"folder": {"ROLE/YES/FOLDER"},
}
r.URL.RawQuery = v.Encode()
r.Header.Set("Cookie", "89825f9123456fa0")
new(http.Client).Do(r)
}
You should also be able to send the query string as the body, in case this doesn't
work.
https://golang.org/pkg/net/http#NewRequest

Opsgenie powershell alert post not working

I have successfully made an alert post using Python, but cannot get my powershell alert creation to work. I just get a wall of HTML in my response and no alert creation. Message is the only required field.
Here's what I'm using and it does not work
$api = "XXX"
$URI = "https://api.opsgenie.com/v2/alerts"
$head = #{"Authorization" = "GenieKey $api"}
$body = #{
message = "testing";
responders =
]#{
name = "TEAMNAMEHERE";
type = "team"
}]
} | ConvertTo-Json
$request = Invoke-RestMethod -Uri $URI -Method Post -Headers $head -ContentType "application/json" -Body $body
$request
Here is my python code I made and it works just fine.
import requests
import json
def CreateOpsGenieAlert(api_token):
header = {
"Authorization": "GenieKey " + api_token,
"Content-Type": "application/json"
}
body = json.dumps({"message": "testing",
"responders": [
{
"name": "TEAMNAMEHERE",
"type": "team"
}
]
}
)
try:
response = requests.post("https://api.opsgenie.com/v2/alerts",
headers=header,
data=body)
jsontemp = json.loads(response.text)
print(jsontemp)
if response.status_code == 202:
return response
except:
print('error')
print(response)
CreateOpsGenieAlert(api_token="XXX")
EDIT: So I've figured out it has something to do with my "responders" section. It has something to do with the [ ]...but I haven't been able to figure out what exactly. If I remove them, it wont work. If I turn the first one around, it won't work. I can get the alert to create successfully, however I keep getting the following error:
] : The term ']' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At \\file\Tech\user\powershell scripts\.not working\OpsGenieAlert.ps1:7 char:17
+ ]#{
+ ~
+ CategoryInfo : ObjectNotFound: (]:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
You need to convert your $body to JSON
$api = "XXX"
$URI = "https://api.opsgenie.com/v2/alerts"
# Declare an empty array
$responders = #()
# Add a new item to the array
$responders += #{
name = "TEAMNAMEHERE1"
type = "team1"
}
$responders += #{
name = "TEAMNAMEHERE2"
type = "team2"
}
$body = #{
message = "testing"
responders = $responders
} | ConvertTo-Json
$invokeRestMethodParams = #{
'Headers' = #{
"Authorization" = "GenieKey $api"
}
'Uri' = $URI
'ContentType' = 'application/json'
'Body' = $body
'Method' = 'Post'
}
$request = Invoke-RestMethod #invokeRestMethodParams

S3 Ajax CORS Error

I have been trying to solve this for the past few hours.
I am using the Heroku S3 python app direct upload method outlined here.
Basically, I have a file input which I get the file from with
$('#files').on('change', function() {
var files = document.getElementById("files").files;
var file = files[0];
if(!file){
return alert("No file selected.");
}
getSignedRequest(file);
})
In getSignedRequest, I make a request to my sign_s3 route
function getSignedRequest(file){
var xhr = new XMLHttpRequest();
xhr.open("GET", "/sign_s3?file_name="+file.name+"&file_type="+file.type);
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status === 200){
var response = JSON.parse(xhr.responseText);
uploadFile(file, response.data, response.url);
}
else{
alert("Could not get signed URL.");
}
}
};
xhr.send();
}
The sign_s3 route is defined as follows
#main.route('/sign_s3/')
def sign_s3():
S3_BUCKET = os.environ.get('S3_BUCKET')
file_name = request.args.get('file_name')
file_type = request.args.get('file_type')
s3 = boto3.client('s3')
presigned_post = s3.generate_presigned_post(
Bucket = S3_BUCKET,
Key = file_name,
Fields = {"acl": "public-read", "Content-Type": file_type},
Conditions = [
{"acl": "public-read"},
{"Content-Type": file_type}
],
ExpiresIn = 3600
)
return json.dumps({
'data': presigned_post,
'url': 'https://%s.s3.amazonaws.com/%s' % (S3_BUCKET, file_name)
})
The uploadFile function is defined as follows
function uploadFile(file, s3Data, url){
var xhr = new XMLHttpRequest();
xhr.open("POST", s3Data.url);
var postData = new FormData();
for(key in s3Data.fields){
postData.append(key, s3Data.fields[key]);
}
postData.append('file', file);
console.log(file);
xhr.onreadystatechange = function() {
if(xhr.readyState === 4){
if(xhr.status === 200 || xhr.status === 204){
document.getElementById("preview").src = url;
document.getElementById("avatar-url").value = url;
}
else{
alert("Could not upload file.");
}
}
};
xhr.send(postData);
}
});
My bucket CORS config is as follows
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>http://localhost:5000</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
But I keep getting the following error upon fileUpload
Failed to load https://mhealth-beta-1.s3.amazonaws.com/: Redirect from 'https://mhealth-beta-1.s3.amazonaws.com/' to 'https://mhealth-beta-1.s3-us-west-2.amazonaws.com/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:5000' is therefore not allowed access.
The error is mentioning a redirect. I'm not familiar with how 302 redirects interact with CORS but try this:
In your backend route, use the dns name including the region.
so 'https://%s.s3.%s.amazonaws.com/%s' % (S3_BUCKET, region, file_name)

Categories

Resources