I've been trying for a while now to connect to the suiteCRM API using Python's request module but to no avail, the official tutorial uses PHP: https://docs.suitecrm.com/developer/api/api-4_1/
I can't seem to create the Python equivalent of this request, no matter what I get the same response:
<pre>/**
* SugarWebServiceImplv4_1.php
*
* This class is an implementation class for all the web services. Version 4_1 adds limit/off support to the
* get_relationships function. We also added the sync_get_modified_relationships function call from version
* one to facilitate querying for related meetings/calls contacts/users records.
*
*/
Class [ <user> class SugarWebServiceImplv4_1 extends SugarWebServiceImplv4 ] {
- Constants [0] {
}
- Static properties [1] {
Property [ public static $helperObject ]
}
- Static methods [0] {
}
- Properties [0] {
}
- Methods [36] {
/**
* Class Constructor Object
*
*/
Method [ <user, overwrites SugarWebServiceImplv4, ctor> public method __construct ] {
}
/**
* Retrieve a collection of beans that are related to the specified bean and optionally return relationship data for those related beans.
* So in this API you can get contacts info for an account and also return all those contact's email address or an opportunity info also.
*
* #param String $session -- Session ID returned by a previous call to login.
* #param String $module_name -- The name of the module that the primary record is from. This name should be the name the module was developed under (changing a tab name is studio does not affect the name that should be passed into this method)..
* #param String $module_id -- The ID of the bean in the specified module
* #param String $link_field_name -- The name of the lnk field to return records from. This name should be the name the relationship.
* #param String $related_module_query -- A portion of the where clause of the SQL statement to find the related items. The SQL query will already be filtered to only include the beans that are related to the specified bean.
... that continues on, it looks like some documentation.
This is my code:
def get_info():
headers = {
"Content-Type": "application/json"
}
creds = OrderedDict()
creds = {"user_auth": {'user_name':"***", "password": "***"}}
creds = json.dumps(creds)
data = {
'method':'login',
'input_type': 'JSON',
'response_type':'JSON',
'rest_data': creds
}
data = json.dumps(data)
response = requests.post("http://example.com/suitecrm/service/v4_1/rest.php", headers=headers, data=data)
print(response.text)
return response.text
Does anyone have any experience doing this? Thank you
edit: this is the PHP call from their docs:
<?php
$url = "http://example.com/suitecrm/service/v4_1/rest.php";
function restRequest($method, $arguments){
global $url;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$post = array(
"method" => $method,
"input_type" => "JSON",
"response_type" => "JSON",
"rest_data" => json_encode($arguments),
);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
$result = curl_exec($curl);
curl_close($curl);
return json_decode($result,1);
}
$userAuth = array(
'user_name' => 'suitecrmuser',
'password' => md5('suitecrmpassword'),
);
$appName = 'My SuiteCRM REST Client';
$nameValueList = array();
$args = array(
'user_auth' => $userAuth,
'application_name' => $appName,
'name_value_list' => $nameValueList);
$result = restRequest('login',$args);
$sessId = $result['id'];
$entryArgs = array(
//Session id - retrieved from login call
'session' => $sessId,
//Module to get_entry_list for
'module_name' => 'Accounts',
//Filter query - Added to the SQL where clause,
'query' => "accounts.billing_address_city = 'Ohio'",
//Order by - unused
'order_by' => '',
//Start with the first record
'offset' => 0,
//Return the id and name fields
'select_fields' => array('id','name',),
//Link to the "contacts" relationship and retrieve the
//First and last names.
'link_name_to_fields_array' => array(
array(
'name' => 'contacts',
'value' => array(
'first_name',
'last_name',
),
),
),
//Show 10 max results
'max_results' => 10,
//Do not show deleted
'deleted' => 0,
);
$result = restRequest('get_entry_list',$entryArgs);
print_r($result);
Please check this working example, it should help you get started. Its using python3.
import urllib.request
import json
import hashlib
encode = hashlib.md5("MasterPass".encode('utf-8'))
encodedPassword = encode.hexdigest()
args = {'user_auth': {'user_name': 'admin','password': encodedPassword}}
crmUrl="https://yourname.crm.cr/service/v4_1/rest.php"
data = json.dumps(args)
args = {'method': 'login', 'input_type': 'json',
'response_type' : 'json', 'rest_data' : data}
params = urllib.parse.urlencode(args).encode('utf-8')
response = urllib.request.urlopen(crmUrl, params)
response = response.read().strip()
if not response:
print( "error: " , response)
result = json.loads(response.decode('utf-8'))
print (result)
Related
I am sending an HTTP request using CURL API in PHP and trying to receive the variable custid in python: How do I receive the custid? Below is the PHP code and also the python code. The url in this example is $temp_url = "https://test.com//api/v1/users/all?custid=123";
PHP Send:
function __pull($temp_url)
{
$curl = curl_init();
$username = "##########";
$password = "##########";
$temp_url = "https://test.com//api/v1/users/all?custid=123";
curl_setopt_array($curl, array(
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_URL => "$temp_url",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_USERPWD => "$username:$password",
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache"
),));
$this->response = curl_exec($curl);
$this->err = curl_error($curl);
curl_close($curl);
$this->response = json_decode($this->response, true); //because of true, it's in an array
//var_dump($this->response);
//print_r($this->err);
if (empty($this->response)) return FALSE; else return TRUE;
}
Here is the Python Code at the designated URL:
#app.route('/api/v1/users/all', methods=['GET'])
#auth.login_required
def get_users():
# what is the code in python to retrieve the variable custid from this url
# https://test.com//api/v1/users/all?custid=123
print(request['custid'])
return TRUE
To get custid in above example, you should request object like below:
def get_users():
custid = request.args.get('custid')
print(custid)
return 'OK'
Basically, the get() method of the args object returns the value of the custid query parameter as a string (or returns None)
So i am making a classified website with wordpress and classima theme, i am testing out upload the image with the help of postman. Below is the theme code responsible for api upload to the website and i couldn't figure out which variable to use in my postman body to upload to website using api. I am able to set new listing title, price and everything but for image i can not figure out how to do it. Please see my attached screenshot of postman for what i have tried
$files = $request->get_file_params();
$uploaded_images = [];
if (!empty($files['gallery']['name'])) {
$gallery = $files['gallery'];
require_once(ABSPATH . 'wp-admin/includes/file.php');
require_once(ABSPATH . 'wp-admin/includes/image.php');
foreach ($gallery['name'] as $key => $value) {
if ($gallery['name'][$key]) {
$image = array(
'name' => $gallery['name'][$key],
'type' => $gallery['type'][$key],
'tmp_name' => $gallery['tmp_name'][$key],
'error' => $gallery['error'][$key],
'size' => $gallery['size'][$key]
);
Filters::beforeUpload();
$status = wp_handle_upload($image, ['test_form' => false]);
Filters::afterUpload();
if ($status && !isset($status['error'])) {
$filename = $status['file'];
$filetype = wp_check_filetype(basename($filename));
$wp_upload_dir = wp_upload_dir();
$attachment = [
'guid' => $wp_upload_dir['url'] . '/' . basename($filename),
'post_mime_type' => $filetype['type'],
'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
'post_content' => '',
'post_status' => 'inherit'
];
$attach_id = wp_insert_attachment($attachment, $filename, $listing_id);
if (!is_wp_error($attach_id)) {
$uploaded_images[$image['name']] = $attach_id;
wp_update_attachment_metadata($attach_id, wp_generate_attachment_metadata($attach_id, $filename));
}
}
}
}
}
$listing = rtcl()->factory->get_listing($listing_id);
I am in the process of incorporating the gate,io rest api and am currently trying to convert the signature function from python to php(laravel).
Apparently there is a bug hiding in the conversion.
Can someone take a look and tell me if this is all correct or if something is missing here?
For improvement suggestions I would be grateful
Python code:
def gen_sign(method, url, query_string=None, payload_string=None):
key = '' # api_key
secret = '' # api_secret
t = time.time()
m = hashlib.sha512()
m.update((payload_string or "").encode('utf-8'))
hashed_payload = m.hexdigest()
s = '%s\n%s\n%s\n%s\n%s' % (method, url, query_string or "", hashed_payload, t)
sign = hmac.new(secret.encode('utf-8'), s.encode('utf-8'), hashlib.sha512).hexdigest()
return {'KEY': key, 'Timestamp': str(t), 'SIGN': sign}
Source: Gate.io API Signature string generation
Php Code:
public function createSignature($method, $url, $query=null, $payload=null, $algo = 'sha256'){
$key = 'xxx';
$secret= 'xxx';
$time = microtime(true);
$hashed_payload = hash_hmac($algo,$query ?? '');
$string = "{$methode}\n{$url}\n{$query ?? ''}\n{$hashed_payload}\n{$time}"
$sign = hash_hmac($algo,$string,$secret)
return ['KEY' => $key, 'Timestamp' => "{$time}", 'SIGN' => $sign]
}
i got the answer, i hope it will helps:
public function buildSignHeaders($method, $resourcePath, $queryParams = [], $payload = null)
{
$fullPath = parse_url(config('gate-io.host'), PHP_URL_PATH) . $resourcePath;
$fmt = "%s\n%s\n%s\n%s\n%s";
$timestamp = time();
$hashedPayload = hash("sha512", ($payload !== null) ? $payload : "");
$signatureString = sprintf(
$fmt,
$method,
$fullPath,
GuzzleHttp\Psr7\build_query($queryParams, false),
$hashedPayload,
$timestamp
);
$signature = hash_hmac("sha512", $signatureString, config('gate-io.apiSecretKey'));
return [
"KEY" => config('gate-io.apiKey'),
"SIGN" => $signature,
"Timestamp" => $timestamp
];
}
Has anyone tried to use the new PaymentElement in Stripe?
According to the documentation, the payment_method_types need to be configured in the server side and the client side will automatically configure it after retrieving the client_secret . I've followed all the steps in the documentation and all other payment methods I've selected are working but the client side will not configure FPX
Here's a screenshot of the output. As you can see, it's configuring card payment, grabpay and alipay but it isn't configuring fpx payment:
Screenshot of Output
Reference to Stripe Documentation that I'm following: https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements
Backend view -Django
# stripe payment key
stripe.api_key = 'sk_test_<<SECRET_KEY>>'
#api_view(['POST'])
def test_payment(request):
data = request.data
amount = int(float(data['amount']) * 100)
intent = stripe.PaymentIntent.create(
amount=amount,
currency='myr',
payment_method_types=['card', 'fpx', 'grabpay', 'alipay', ],
)
return Response(status=status.HTTP_200_OK, data=intent)
placeorder.js
import React, {useState, useEffect} from 'react'
import axios from 'axios'
//UI components
import Message from '../components/Message'
import Loader from '../components/Loader'
//---------- STRIPE PAYMENT COMPONENTS -------------//
import {Elements} from '#stripe/react-stripe-js'
import {loadStripe} from "#stripe/stripe-js/pure"
import CheckoutForm from "../components/CheckoutForm"
//dev-based publishable key
const stripePromise = loadStripe('pk_test_<<PUBLISHABLE_KEY');
const PlaceOrder = () => {
/* .
.
bunch of other code
.
.
-----*/
const [amount, setAmount] = useState(0)
let [clientSecret, setClientSecret] = useState('')
useEffect(()=> {
if(cart.totalPrice > 0) {
setAmount(cart.totalPrice )
}
//get client_secret
(async () => {
if(amount>0 && clientSecret === ''){
//fetch client secret
const response = await axios.post('/api/orders/payment/test-payment/',
{'amount':amount}
)
// set client secret
const cs = await response.data.client_secret
setClientSecret(cs)
setStripeLoading(false)
}
})()
if(!stripeLoading){
setOptions({
clientSecret: clientSecret,
appearance : {
theme: 'stripe'
}
})
console.log("options2:", options)
}
},[amount, cart.totalPrice, stripeLoading])
return (
<>
{(options === '')
? <Loader/>
: <Elements stripe={stripePromise} options={options} >
<CheckoutForm amount={amount} method={paymentMethod}/>
</Elements>
}
</>)}
export default PlaceOrder
Checkout.js
import React, {useState, useEffect} from 'react'
//stripe componetns
import {useStripe, useElements, PaymentElement} from '#stripe/react-stripe-js';
//UI elements
import {Form, Button, Row, Col} from 'react-bootstrap'
import Message from './Message'
import Loader from './Loader'
const CheckoutForm = ({amount, method}) => {
const [error, setError] = useState('')
const [email, setEmail] = useState('');
const stripe = useStripe()
const elements = useElements()
const handleSubmit = async (e) => {
//prevent default submission and page refresh
e.preventDefault();
if (!stripe || !elements) {
// Stripe.js has not yet loaded.
setError("Stripe or Stripe elements have not loaded yet")
return;
}
const {error} = await stripe.confirmPayment({
//`Elements` instance that was used to create the Payment Element
elements,
confirmParams: {
return_url: '/placeorder',
},
if (error) {
setError("Error: Something went wrong")
}
});
return (
<Form onSubmit={handleSubmit} className="stripe-form">
{/* display error message */}
{error && <Message variant="danger">{error}</Message>}
<PaymentElement id="payment-element"/>
<div className="d-grid">
<Button type="submit" variant="primary" className="my-3 mt-4" disabled={!stripe}>
Submit Payment
</Button>
</div>
</Form>
)
}
export default CheckoutForm
PS. I haven't yet configured stripe to accept payments yet. I'm still trying to figure out why it won't configure FPXPayments in the PaymentElement in the frontend.
Thanks in advance!
previously FPX wasn't available in the Payment Element, but it is now. You can see supported payment methods here.
I have this php api request example I want to convert to python
function sendRequest($url, $params, $apiKey, $secretKey) {
$query = http_build_query($params);
$params['api_key'] = $apiKey;
$params['auth_hash'] = hash_hmac('sha512', $query, $secretKey);
$params['nonce'] = explode(' ', microtime())[1];
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($params),
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_RETURNTRANSFER => true
));
$response = curl_exec($ch);
curl_close($ch);
return $response;}
And this is my python code but it keep returning incorrect hash, please how can I make this request in python?
import hashlib
import hmac
import requests
import time
params = {
'name':'Matthew Jackson',
'state':'nj',
'zip':'034572',
'address':'14 Main Street',
'phone':'',
'dob':''}
def request_ss( url, params, api_key, secretKey):
tosign = "&".join( [i + '=' + params[i] for i in params] )
secretKey = str.encode(secretKey)
tosign = str.encode(tosign)
sign = hmac.new(secretKey, tosign , hashlib.sha512)
res_body = {
'api_key': api_key,
'auth_hash': sign.hexdigest(),
'nonce': str(time.time())}
r = requests.post(url, data=res_body)
return r.text
create_url = 'api_url'
res = request_ss(create_url,params,api_key, api_secret)
print(res)
This code keep returning wrong hash from the server, I don't know if am right or wrong on the way I coded this on python, The goal is just to make a request and get the data from the server, the API provider only give the request example in php in which I don't understand. Your support is going to be highly appriciated