From 8d6094b35dc4d37a6e14628569db19542513c3c5 Mon Sep 17 00:00:00 2001 From: Deeka Wong Date: Mon, 12 Jun 2023 13:10:10 +0800 Subject: [PATCH] Adds `openai-client` (#237) * Adds `openai-client` component * Optimize CI --------- Co-authored-by: Deeka Wong <8337659+huangdijia@users.noreply.github.com> --- .gitattributes | 4 ++ .github/workflows/close-pull-request.yml | 13 ++++ .github/workflows/release.yaml | 25 ++++++++ LICENSE | 21 +++++++ README.md | 77 ++++++++++++++++++++++++ composer.json | 43 +++++++++++++ publish/openai.php | 16 +++++ src/ClientFactory.php | 40 ++++++++++++ src/ConfigProvider.php | 37 ++++++++++++ src/Exception/ApiKeyIsMissing.php | 29 +++++++++ 10 files changed, 305 insertions(+) create mode 100644 .gitattributes create mode 100644 .github/workflows/close-pull-request.yml create mode 100644 .github/workflows/release.yaml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 composer.json create mode 100644 publish/openai.php create mode 100644 src/ClientFactory.php create mode 100644 src/ConfigProvider.php create mode 100644 src/Exception/ApiKeyIsMissing.php diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..c90148b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +/.github export-ignore +/.vscode export-ignore +/tests export-ignore +.gitattributes export-ignore \ No newline at end of file diff --git a/.github/workflows/close-pull-request.yml b/.github/workflows/close-pull-request.yml new file mode 100644 index 0000000..fa4b5ca --- /dev/null +++ b/.github/workflows/close-pull-request.yml @@ -0,0 +1,13 @@ +name: Close Pull Request + +on: + pull_request_target: + types: [opened] + +jobs: + run: + runs-on: ubuntu-latest + steps: + - uses: superbrothers/close-pull-request@v3 + with: + comment: "Thank you for your pull request. However, you have submitted this PR on the friendsofhyperf organization which is a read-only sub split of `friendsofhyperf/components`. Please submit your PR on the https://github.com/friendsofhyperf/components repository.

Thanks!" diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..dde70ae --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,25 @@ +on: + push: + # Sequence of patterns matched against refs/tags + tags: + - 'v*' # Push events to matching v*, i.e. v1.0, v1.0.0 + +name: Release + +jobs: + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }} + draft: false + prerelease: false \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bf891ca --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 D.J.Hwang + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..8ec8b07 --- /dev/null +++ b/README.md @@ -0,0 +1,77 @@ +# Hyperf OpenAI Client + +[![Latest Test](https://github.com/friendsofhyperf/openai-client/workflows/tests/badge.svg)](https://github.com/friendsofhyperf/openai-client/actions) +[![Latest Version on Packagist](https://img.shields.io/packagist/v/friendsofhyperf/openai-client.svg?style=flat-square)](https://packagist.org/packages/friendsofhyperf/openai-client) +[![Total Downloads](https://img.shields.io/packagist/dt/friendsofhyperf/openai-client.svg?style=flat-square)](https://packagist.org/packages/friendsofhyperf/openai-client) +[![GitHub license](https://img.shields.io/github/license/friendsofhyperf/openai-client)](https://github.com/friendsofhyperf/openai-client) + +------ +**OpenAI PHP** for Laravel is a supercharged community PHP API client that allows you to interact with the [Open AI API](https://beta.openai.com/docs/api-reference/introduction). + +> **Note:** This repository contains the integration code of the **OpenAI PHP** for Hyperf. If you want to use the **OpenAI PHP** client in a framework-agnostic way, take a look at the [openai-php/client](https://github.com/openai-php/client) repository. + +## Get Started + +> **Requires [PHP 8.1+](https://php.net/releases/)** + +First, install OpenAI via the [Composer](https://getcomposer.org/) package manager: + +```bash +composer require friendsofhyperf/openai-client +``` + +Next, publish the configuration file: + +```bash +php bin/hyperf.php vendor:publish friendsofhyperf/openai-client +``` + +This will create a `config/autoload/openai.php` configuration file in your project, which you can modify to your needs +using environment variables: + +```env +OPENAI_API_KEY=sk-... +``` + +Finally, you may use the `OpenAI\Client` instance from container to access the OpenAI API: + +```php +use OpenAI\Client; + +$result = di(OpenAI\Client::class)->completions()->create([ + 'model' => 'text-davinci-003', + 'prompt' => 'PHP is', +]); + +echo $result['choices'][0]['text']; // an open-source, widely-used, server-side scripting language. +``` + +## Azure + +In order to use the Azure OpenAI Service, it is necessary to construct the client manually using the factory. + +```php +$client = OpenAI::factory() + ->withBaseUri('{your-resource-name}.openai.azure.com/openai/deployments/{deployment-id}') + ->withHttpHeader('api-key', '{your-api-key}') + ->withQueryParam('api-version', '{version}') + ->make(); +``` + +To use Azure, you must deploy a model, identified by the {deployment-id}, which is already incorporated into the API calls. As a result, you do not have to provide the model during the calls since it is included in the BaseUri. + +Therefore, a basic sample completion call would be: + +```php +$result = $client->completions()->create([ + 'prompt' => 'PHP is' +]); +``` + +## Usage + +For usage examples, take a look at the [openai-php/client](https://github.com/openai-php/client) repository. + +--- + +OpenAI PHP for Hyperf is an open-sourced software licensed under the **[MIT license](https://opensource.org/licenses/MIT)**. diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..47fd6d3 --- /dev/null +++ b/composer.json @@ -0,0 +1,43 @@ +{ + "name": "friendsofhyperf/openai-client", + "description": "The openai client component for Hyperf.", + "type": "library", + "keywords": [ + "hyperf", + "openai" + ], + "homepage": "https://github.com/friendsofhyperf/openai-client", + "license": "MIT", + "authors": [ + { + "name": "huangdijia", + "email": "huangdijia@gmail.com" + } + ], + "require": { + "php": ">=8.1", + "hyperf/config": "~3.0.0", + "hyperf/di": "~3.0.0", + "hyperf/guzzle": "~3.0.0", + "openai-php/client": "^0.5.1" + }, + "autoload": { + "psr-4": { + "FriendsOfHyperf\\OpenAi\\": "src/" + } + }, + "extra": { + "hyperf": { + "config": "FriendsOfHyperf\\OpenAi\\ConfigProvider" + } + }, + "config": { + "sort-packages": true + }, + "minimum-stability": "dev", + "prefer-stable": true, + "support": { + "issues": "https://github.com/friendsofhyperf/components/issues", + "source": "https://github.com/friendsofhyperf/components" + } +} diff --git a/publish/openai.php b/publish/openai.php new file mode 100644 index 0000000..a1ab56d --- /dev/null +++ b/publish/openai.php @@ -0,0 +1,16 @@ + env('OPENAI_API_KEY', ''), + 'organization' => env('OPENAI_ORGANIZATION'), +]; diff --git a/src/ClientFactory.php b/src/ClientFactory.php new file mode 100644 index 0000000..8d5843f --- /dev/null +++ b/src/ClientFactory.php @@ -0,0 +1,40 @@ +withApiKey($apiKey) + ->withOrganization($organization) + ->withBaseUri('api.openai.com/v1') + ->withHttpClient( + $container->get(GuzzleClientFactory::class)->create() + ) + ->make(); + } +} diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php new file mode 100644 index 0000000..3023864 --- /dev/null +++ b/src/ConfigProvider.php @@ -0,0 +1,37 @@ + [ + Client::class => ClientFactory::class, + ClientContract::class => fn ($container) => $container->get(Client::class), // alias for Client::class + ], + 'publish' => [ + [ + 'id' => 'config', + 'description' => 'The config file for OpenAI.', + 'source' => __DIR__ . '/../publish/openai.php', + 'destination' => BASE_PATH . '/config/autoload/openai.php', + ], + ], + ]; + } +} diff --git a/src/Exception/ApiKeyIsMissing.php b/src/Exception/ApiKeyIsMissing.php new file mode 100644 index 0000000..b8c3724 --- /dev/null +++ b/src/Exception/ApiKeyIsMissing.php @@ -0,0 +1,29 @@ +