Perl's OpenAPI::Client - how to pass additionalProperties in OpenAPI GET query request? - perl

I'm trying to pass filter variables in a GET request to an OpenAPI route with this specification:
- in: query
name: params
schema:
type: object
additionalProperties:
type: string
style: form
explode: true
I've tried various different ways of passing the data at request time:
my $client = OpenAPI::Client->new(...);
my $tx = $client->findApps({
params => { 'id' => '1' }
});
my $tx = $client->findApps({ 'id' => '1' });
What is the correct way to do this?

Related

How to use aggregations framework in new Elasticsearch using Perl language

I am working on Elasticsearch and I have to do aggregations (i.e used for summarize our data) I shared my code below....
CODE:
my $portal_es = Search::Elasticsearch->new(nodes => [$es_ip.':'.$es_port],request_timeout => 180);
my $result = $portal_es->scroll_helper(index => 10002500,size =>"10000", params=>{rest_total_hits_as_int =>true},{
#"size": 0,
aggs=> {
"my-agg-name"=> {
terms=> {
field=> "tcode"
}
}
}
});
I am getting following error
[Param] ** Expecting a HASH ref or a list of key-value pairs, called from sub Search::Elasticsearch::Role::Client::Direct::Main::scroll_helper at /home/prity/Desktop/BL_script/search_index_processor/aggregation.pl line 15. With vars: {'params' => ['index','10002500','size','10000','params',{'rest_total_hits_as_int' => 'true'},{'aggs' => {'my-agg-name' => {'terms' => {'field' => 'tcode'}}}}]}
The data structure in your argument list is probably broken.
my $result = $portal_es->scroll_helper(
index => 10002500,
size => "10000",
params => {
rest_total_hits_as_int => 'true'
},
{ # <---- here
aggs => {
# ...
You are passing a list of key/value pairs into the scroll_helper, but there is one extra last argument after params. It's a hash reference with aggs in it that has no key for it.
Turn on use warnings and you'll get a warning that your data structure is missing a value (because that hashref will stringify into a key).
You probably shouldn't have closed the hashref for params and opened a new one. But that's just a guess, I don't know what this method expects.

ApiPlatform Regex property filter with Postgresql

I'm trying to add a custom filter to an entity in my ApiPlatform project that allows me to filter on specific property given a regex pattern.
Following the ApiPlatform documentation I came up with the following class (this is a near copy of the their example, only the where-clause is different):
<?php
namespace App\Filter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractContextAwareFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use Doctrine\ORM\QueryBuilder;
final class RegexFilter extends AbstractContextAwareFilter
{
protected function filterProperty(
string $property,
$value,
QueryBuilder $queryBuilder,
QueryNameGeneratorInterface $queryNameGenerator,
string $resourceClass,
string $operationName = null
) {
// otherwise filter is applied to order and page as well
if (
!$this->isPropertyEnabled($property, $resourceClass) ||
!$this->isPropertyMapped($property, $resourceClass)
) {
return;
}
$parameterName = $queryNameGenerator->generateParameterName($property); // Generate a unique parameter name to avoid collisions with other filters
$queryBuilder
->andWhere(sprintf('(o.%s ~ :%s) = true', $property, $parameterName))
->setParameter($parameterName, $value);
}
// This function is only used to hook in documentation generators (supported by Swagger and Hydra)
public function getDescription(string $resourceClass): array
{
if (!$this->properties) {
return [];
}
$description = [];
foreach ($this->properties as $property => $strategy) {
$description["regexp_$property"] = [
'property' => $property,
'type' => 'string',
'required' => false,
'swagger' => [
'description' => 'Filter using a regex. This will appear in the Swagger documentation!',
'name' => 'Custom name to use in the Swagger documentation',
'type' => 'Will appear below the name in the Swagger documentation',
],
];
}
return $description;
}
}
When I run my code this results in the following DQL:
SELECT o FROM App\Entity\Vehicle o WHERE (o.licensePlate ~ :licensePlate_p1) = true ORDER BY o.id ASC
However I cannot get the Lexer to understand the tilde ~ character:
Doctrine\ORM\Query\QueryException
[Syntax Error] line 0, col 56: Error: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS, got '~'
How can I make Doctrine understand the tilde?
Turns out I was pretty close, simPod's answer helped me fill the gaps.
I copied his custom DQL function and added it in my Doctrine yaml configuration
In my RegexFilter I had to slightly modify the where-clause:
->andWhere(sprintf('REGEX(o.%s, :%s) = true', $property, $parameterName))

Perl script with JIRA REST-API to create JIRA along with custom field

We are unable to create the new ticket in Jira using REST-API via Perl script.
Note: Without custom field script successfully executing. please provide the suggestion to add a custom field in my script.
Screenshot for the custom field.
Error Message:
JIRA::REST Error[400 - Bad Request]:
- [custom_field] Field 'custom_field' cannot be set. It is not on the appropriate screen, or unknown.at copy_of_new-jira.pl line 16.
Perl Script :
#Loading the modules from a specific location such that JIRA::REST.
use JIRA::Client::Automated;
use JIRA::REST;
use Data::Dumper;
#Login details about Jira server
my $jira = JIRA::REST->new({
url => 'https://xxxxxxxx.xxxxx.com',
username => 'xxxxxxx',
password => 'xxxxxxx',
});
# Create the ticket using post function
my $issue = $jira->POST('/issue', undef, {
fields => {
project => { key => 'TIME' },
issuetype => { name => 'Task' },
summary => '20-7-2018 checking field persent or not',
description => 'test',
custom_field => { Epic Link => 'Application Framework'},
},
});
It looks like you're missing some quote marks in your fields->custom_field data structure:
# Create the ticket using post function
my $issue = $jira->POST('/issue', undef, {
fields => {
project => { key => 'TIME' },
issuetype => { name => 'Task' },
summary => '20-7-2018 checking field persent or not',
description => 'test',
custom_field => { 'Epic Link' => 'Application Framework'},
},
});
There's also a typo in summary, but presumably that doesn't matter too much.

How to get the query parameters in a Guzzle/ Psr7 request

I am using Guzzle 6.
I am trying to mock a client and use it like so:
<?php
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
$mock_handler = new MockHandler([
new Response(200, ['Content-Type' => 'application/json'], 'foo'),
]);
$history = [];
$history_middleware = Middleware::history($history);
$handler_stack = HandlerStack::create($mock_handler);
$handler_stack->push($history_middleware);
$mock_client = new Client(['handler' => $handler_stack]);
// Use mock client in some way
$mock_client->get("http://example.com", [
'query' => [
'bar' => '10',
'hello' => '20'
],
]);
// ------
// get original request using history
$transaction = $history[0];
/** #var Request $request */
$request = $transaction['request'];
// How can I get the query parameters that was used in the request (i.e. bar)
My question is how can I get the query parameters used in the GuzzleHttp\Psr7\Request class?
The closest I managed to get is the following: $request->getUri()->getQuery(), but this just returns a string like so: bar=10&hello=20.
I seem to have solved my problem.
I can simply do this:
parse_str($request->getUri()->getQuery(), $query);
and I now have an array of the query parameters.
Other solutions are welcome!

Multiple duplicate uri parameters in GuzzleHttp

I am accessing the Echo Nest API, which requires me to repeat the same uri parameter name bucket. However I can't make this work in Guzzle 6. I read a similar issue from 2012, however the approach does not work.
I have tried adding it manually into the query string without any success.
A sample API call could be:
http://developer.echonest.com/api/v4/song/search?format=json&results=10&api_key=someKey&artist=Silbermond&title=Ja&bucket=id:spotify&bucket=tracks&bucket=audio_summary
Here's my example Client:
/**
* #param array $urlParameters
* #return Client
*/
protected function getClient()
{
return new Client([
'base_uri' => 'http://developer.echonest.com/api/v4/',
'timeout' => 5.0,
'headers' => [
'Accept' => 'application/json',
],
'query' => [
'api_key' => 'someKey',
'format' => 'json',
'results' => '10',
'bucket' => 'id:spotify' // I need multiple bucket parameter values with the 'bucket'-name
]);
}
/**
* #param $artist
* #param $title
* #return stdClass|null
*/
public function searchForArtistAndTitle($artist, $title)
{
$response = $this->getClient()->get(
'song/search?' . $this->generateBucketUriString(),
[
'query' => array_merge($client->getConfig('query'), [
'artist' => $artist,
'title' => $title
])
]
);
// ...
}
Can you help me?
In the Guzzle 6 you are not allowed to pass any aggregate function anymore. Whenever you will pass an array to the query config it will be serialized with the http_build_query function:
if (isset($options['query'])) {
$value = $options['query'];
if (is_array($value)) {
$value = http_build_query($value, null, '&', PHP_QUERY_RFC3986);
}
To avoid it you should serialize a query string by your own and pass it as string.
new Client([
'query' => $this->serializeWithDuplicates([
'bucket' => ['id:spotify', 'id:spotify2']
]) // serialize the way to get bucket=id:spotify&bucket=id:spotify2
...
$response = $this->getClient()->get(
...
'query' => $client->getConfig('query').$this->serializeWithDuplicates([
'artist' => $artist,
'title' => $title
])
...
);
Otherwise you could pass into the handler option an adjusted HandlerStack that will have in its stack your Middleware Handler. The one will read some new config param, say, query_with_duplicates, build acceptable Query String and modify Request's Uri with it accordingly.
I had the same need today, but now we are on Guzzle 7, the easiest way of getting duplicates for params (bucket=value1&bucket=value2&bucket=value3...) is to use the Query Build method. For this to work do the following:
// Import the class
use GuzzleHttp\Psr7\Query;
Example params
$params = [
'bucket' => 'value1',
'bucket' => 'value2',
'bucket' => 'value3',
];
Then when passing the params array to the query key, first pass it through the Query::build method
$response = $client->get('/api', [
'query' => Query::build($params),
]);