diff --git a/README.md b/README.md index 6f74127..f74200c 100644 --- a/README.md +++ b/README.md @@ -25,17 +25,19 @@ First, install OpenAI via the [Composer](https://getcomposer.org/) package manag composer require openai-php/laravel ``` -Next, publish the configuration file: +Then execute the install command: ```bash -php artisan vendor:publish --provider="OpenAI\Laravel\ServiceProvider" +php artisan openai:install ``` This will create a `config/openai.php` configuration file in your project, which you can modify to your needs -using environment variables: +using environment variables. +The environment variables for the OpenAI API key and organization id are already added to your `.env` file. ```env OPENAI_API_KEY=sk-... +OPENAI_ORGANIZATION=org-... ``` Finally, you may use the `OpenAI` facade to access the OpenAI API: diff --git a/resources/views/components/badge.php b/resources/views/components/badge.php new file mode 100644 index 0000000..df99a59 --- /dev/null +++ b/resources/views/components/badge.php @@ -0,0 +1,17 @@ + ['blue', 'INFO'], + 'ERROR' => ['red', 'ERROR'], +}; + +?> + +
+ + + + +
diff --git a/resources/views/components/new-line.php b/resources/views/components/new-line.php new file mode 100644 index 0000000..7c89b54 --- /dev/null +++ b/resources/views/components/new-line.php @@ -0,0 +1 @@ +
diff --git a/resources/views/components/two-column-detail.php b/resources/views/components/two-column-detail.php new file mode 100644 index 0000000..152f20b --- /dev/null +++ b/resources/views/components/two-column-detail.php @@ -0,0 +1,12 @@ +
+ + + + + + + + + +
+ diff --git a/src/Commands/InstallCommand.php b/src/Commands/InstallCommand.php new file mode 100644 index 0000000..fb26c62 --- /dev/null +++ b/src/Commands/InstallCommand.php @@ -0,0 +1,140 @@ + 'https://github.com/openai-php/laravel', + 'OpenAI PHP Docs' => 'https://github.com/openai-php/client#readme', + 'Join us on Telegram' => 'https://t.me/+66GDs6UM6RcxY2U8', + ]; + + private const FUNDING_LINKS = [ + 'Sponsor Sandro' => 'https://github.com/sponsors/gehrisandro', + 'Sponsor Nuno' => 'https://github.com/sponsors/nunomaduro', + ]; + + protected $signature = 'openai:install'; + + protected $description = 'Prepares the OpenAI client for use.'; + + public function handle(): void + { + View::renderUsing($this->output); + + View::render('components.badge', [ + 'type' => 'INFO', + 'content' => 'Installing OpenAI for Laravel.', + ]); + + $this->copyConfig(); + + View::render('components.new-line'); + + $this->addEnvKeys('.env'); + $this->addEnvKeys('.env.example'); + + View::render('components.new-line'); + + $wantsToSupport = $this->askToStarRepository(); + + $this->showLinks(); + + View::render('components.badge', [ + 'type' => 'INFO', + 'content' => 'Open your .env and add your OpenAI API key and organization id.', + ]); + + if ($wantsToSupport) { + $this->openRepositoryInBrowser(); + } + } + + private function copyConfig(): void + { + if (file_exists(config_path('openai.php'))) { + View::render('components.two-column-detail', [ + 'left' => 'config/openai.php', + 'right' => 'File already exists.', + ]); + + return; + } + + View::render('components.two-column-detail', [ + 'left' => 'config/openai.php', + 'right' => 'File created.', + ]); + + $this->callSilent('vendor:publish', [ + '--provider' => ServiceProvider::class, + ]); + } + + private function addEnvKeys(string $envFile): void + { + $fileContent = file_get_contents(base_path($envFile)); + + if ($fileContent === false) { + return; + } + + if (str_contains($fileContent, 'OPENAI_API_KEY')) { + View::render('components.two-column-detail', [ + 'left' => $envFile, + 'right' => 'Variables already exists.', + ]); + + return; + } + + file_put_contents(base_path($envFile), PHP_EOL.'OPENAI_API_KEY='.PHP_EOL.'OPENAI_ORGANIZATION='.PHP_EOL, FILE_APPEND); + + View::render('components.two-column-detail', [ + 'left' => $envFile, + 'right' => 'OPENAI_API_KEY and OPENAI_ORGANIZATION variables added.', + ]); + } + + private function askToStarRepository(): bool + { + if (! $this->input->isInteractive()) { + return false; + } + + return $this->confirm(' Wanna show OpenAI for Laravel some love by starring it on GitHub?', false); + } + + private function openRepositoryInBrowser(): void + { + if (PHP_OS_FAMILY == 'Darwin') { + exec('open https://github.com/openai-php/laravel'); + } + if (PHP_OS_FAMILY == 'Windows') { + exec('start https://github.com/openai-php/laravel'); + } + if (PHP_OS_FAMILY == 'Linux') { + exec('xdg-open https://github.com/openai-php/laravel'); + } + } + + private function showLinks(): void + { + $links = [ + ...self::LINKS, + ...rand(0, 1) ? self::FUNDING_LINKS : array_reverse(self::FUNDING_LINKS, true), + ]; + + foreach ($links as $message => $link) { + View::render('components.two-column-detail', [ + 'left' => $message, + 'right' => $link, + ]); + } + } +} diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index e7d3344..976fcee 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -9,6 +9,7 @@ use OpenAI; use OpenAI\Client; use OpenAI\Contracts\ClientContract; +use OpenAI\Laravel\Commands\InstallCommand; use OpenAI\Laravel\Exceptions\ApiKeyIsMissing; /** @@ -50,6 +51,10 @@ public function boot(): void $this->publishes([ __DIR__.'/../config/openai.php' => config_path('openai.php'), ]); + + $this->commands([ + InstallCommand::class, + ]); } } diff --git a/src/Support/View.php b/src/Support/View.php new file mode 100644 index 0000000..05b036b --- /dev/null +++ b/src/Support/View.php @@ -0,0 +1,72 @@ + $data + */ + public static function render(string $path, array $data = []): void + { + $contents = self::compile($path, $data); + + $existing = Termwind::getRenderer(); + + renderUsing(self::$output); + + try { + render($contents); + } finally { + renderUsing($existing); + } + } + + /** + * Compiles the given view. + * + * @param array $data + */ + private static function compile(string $path, array $data): string + { + extract($data); + + ob_start(); + + $path = str_replace('.', '/', $path); + + include sprintf('%s/../../resources/views/%s.php', __DIR__, $path); + + $contents = ob_get_contents(); + + ob_clean(); + + return (string) $contents; + } +}