Created
January 18, 2023 01:30
-
-
Save AzureFlow/f6f44bf0c2cab2b205a59067a1d1cd07 to your computer and use it in GitHub Desktop.
Simple Wolfram|Alpha client in PHP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use AzureFlow\WolfApi\QueryBuilder; | |
use GuzzleHttp\Client; | |
use GuzzleHttp\RequestOptions; | |
require __DIR__ . '/../vendor/autoload.php'; | |
// Docs | |
// https://products.wolframalpha.com/api/documentation | |
// https://github.com/aeurielesn/wolfram-alpha-java-binding | |
// https://github.com/francescomalatesta/wolframalphaphp | |
// https://github.com/larrabyte/bakerbot/blob/a64b2e29bafc0ab6e6c1da2d3f842667ef15af52/backends/wolfram.py | |
// https://github.com/scalarwaves/iloa/blob/ba20464f0df52b2c8a37d67619afebe21d17a1da/src/commands/wolfram.js#L103 | |
// salt: EumRuvaOhx7ENr9N | |
// legacy: Y5H46L-2KR8T4PPQQ | |
// pro: Y5H46L-VGTX7EAWVP | |
// consumerSecretPro: kGnawxw9fUUTyD8lHUJgJ29i+M6HjzHoxCTJbwupppY= | |
// consumerKeyPro: kSJ68leuI9qCVleZ+Xt50uDOBkN9FlhH/c/Fh9mZF1A= | |
// mobileProAppApiKey: 4c83bda499424d2eb03631fe48e79cee | |
const API_URL = 'https://api.wolframalpha.com/v2/query.jsp'; | |
const APP_ID = 'Y5H46L-2KR8T4PPQQ'; | |
const APP_SALT = 'EumRuvaOhx7ENr9N'; | |
$client = new Client([ | |
RequestOptions::HEADERS => [ | |
'Accept' => '*/*', | |
'User-Agent' => 'Wolfram|Alpha Java Binding 1.1', | |
'Accept-Language' => 'en-US,en;q=0.9', | |
], | |
]); | |
// https://products.wolframalpha.com/api/documentation?scrollTo=pod-states | |
// $formats = ['png','plaintext','imagemap','minput','sound']; | |
$formats = ['plaintext']; | |
// Example query | |
// appid: Y5H46L-2KR8T4PPQQ | |
// input: x^2 +5x +6=0 | |
// banners: image | |
// format: png,plaintext,imagemap,minput,sound | |
// async: false | |
// scantimeout: 25.0 | |
// podtimeout: 25.0 | |
// formattimeout: 25.0 | |
// countrycode: US | |
// languagecode: en | |
// sidebarlinks: true | |
// includepodid: Solution | |
// podstate: Solution__Step-by-step solution | |
// width: 1328 | |
// maxwidth: 2760 | |
// mag: 3.5 | |
// device: Android | |
// sig: 57A5148397C56B4C6E3AB05F9413EE6D | |
$query = new QueryBuilder(); | |
$query->add('appid', APP_ID); | |
$query->add('input', 'x^2 + 5x + 6 = 0'); | |
$query->add('output', 'json'); | |
// $query->add('banners', 'image'); | |
// $query->add('async', 0.25); | |
// $query->add('scantimeout', 0.5); | |
// $query->add('sidebarlinks', true); | |
// $query->add('podtimeout', true); | |
// $query->add('width', 1328); | |
// $query->add('maxwidth', 2760); | |
// $query->add('mag', 3.5); | |
$query->add('format', implode(',', $formats)); | |
$query->add('podstate', 'Solution__Step-by-step solution'); | |
$query->add('podstate', 'Solution__Use factor method'); | |
$query->add('includepodid', 'Solution'); | |
// $query->add('countrycode', 'US'); | |
// $query->add('languagecode', 'en'); | |
$query->add('device', 'Android'); | |
$resp = $client->get(API_URL, [ | |
RequestOptions::QUERY => $query->build(), | |
]); | |
$result = json_decode($resp->getBody()->getContents(), true, 512, JSON_THROW_ON_ERROR)['queryresult']; | |
if($result['numpods'] > 0) | |
{ | |
echo end($result['pods'][0]['subpods'])['plaintext'] . PHP_EOL; | |
} | |
else | |
{ | |
$msg = isset($result['error']) ? $result['error']['msg'] : 'N/A'; | |
echo "ERROR: $msg" . PHP_EOL; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php declare(strict_types=1); | |
namespace AzureFlow\WolfApi; | |
class QueryBuilder | |
{ | |
private array $parts = []; | |
public function add(string $key, mixed $value): void | |
{ | |
$this->parts[] = [ | |
'key' => $key, | |
'value' => (string) $value, | |
]; | |
} | |
public function build(): string | |
{ | |
usort($this->parts, static function($item1, $item2) { | |
return strnatcmp($item1['key'], $item2['key']); | |
}); | |
$queryString = implode( | |
'&', | |
array_map(static function($part) { | |
return urlencode($part['key']) . '=' . urlencode($part['value']); | |
}, $this->parts) | |
); | |
$sigString = $this->generateSignature(); | |
return "$queryString&sig=$sigString"; | |
} | |
public function __toString() | |
{ | |
return $this->build(); | |
} | |
protected function generateSignature(): string | |
{ | |
$queryStr = implode( | |
'', | |
array_map(static function($part) { | |
return urlencode($part['key']) . urlencode($part['value']); | |
}, $this->parts) | |
); | |
return strtoupper(md5(APP_SALT . $queryStr)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment