diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml new file mode 100644 index 0000000..a27b9e1 --- /dev/null +++ b/.github/workflows/code-quality.yml @@ -0,0 +1,39 @@ +name: Code Quality + +on: ['push'] + +jobs: + ci: + runs-on: ubuntu-latest + + strategy: + fail-fast: true + matrix: + php-version: [8.2] + + name: Code Quality + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Cache dependencies + uses: actions/cache@v1 + with: + path: ~/.composer/cache/files + key: php-${{ matrix.php-version }}-composer-${{ hashFiles('composer.json') }} + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + coverage: none + + - name: Install Composer dependencies + run: composer update --no-interaction --prefer-stable --prefer-dist + + - name: Coding Style Checks + run: composer test:lint + + - name: Types Checks + run: composer test:types diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..92a83cd --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,47 @@ +name: Tests + +on: ['push'] + +jobs: + ci: + runs-on: ubuntu-latest + + strategy: + fail-fast: true + matrix: + php-version: [8.1, 8.2, 8.3] + laravel: [11.*, 10.*, 9.*] + dependency-version: [prefer-lowest, prefer-stable] + exclude: + - php-version: 8.1 + laravel: 11.* + + name: Tests P${{ matrix.php-version }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }} + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Cache dependencies + uses: actions/cache@v1 + with: + path: ~/.composer/cache/files + key: php-${{ matrix.php-version }}-laravel-${{ matrix.laravel }}-${{ matrix.dependency-version }}-composer-${{ hashFiles('composer.json') }} + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + coverage: none + + - name: Require Laravel Version + run: > + composer require --dev + "laravel/framework:${{ matrix.laravel }}" + --no-interaction --no-update + + - name: Install Composer dependencies + run: composer update --${{ matrix.dependency-version }} --no-interaction --prefer-dist + + - name: Unit Tests + run: composer test:unit diff --git a/.gitignore b/.gitignore index 297959a..8475559 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,6 @@ +composer.phar /vendor/ -node_modules/ -npm-debug.log -yarn-error.log - -# Laravel 4 specific -bootstrap/compiled.php -app/storage/ - -# Laravel 5 & Lumen specific -public/storage -public/hot - -# Laravel 5 & Lumen specific with changed public path -public_html/storage -public_html/hot - -storage/*.key -.env -Homestead.yaml -Homestead.json -/.vagrant -.phpunit.result.cache +/composer.lock +/.php-cs-fixer.cache +/.phpunit.cache/ +.idea diff --git a/README.md b/README.md index de2e4b3..70f5cfb 100644 --- a/README.md +++ b/README.md @@ -1 +1,157 @@ -# laravel \ No newline at end of file +
+ +
+ + +# Gemini API Client for Laravel + +Gemini API Client for Laravel allows you to use the Google's generative AI models, like Gemini Pro and Gemini Pro Vision in your Laravel application. + +Supports PHP 8.1 and Laravel v9, v10. + +_This library is not developed or endorsed by Google._ + +- Erdem Köse - **[github.com/erdemkose](https://github.com/erdemkose)** + +## Table of Contents +- [Installation](#installation) +- [Configuration](#configuration) +- [How to use](#how-to-use) + - [Text Generation](#text-generation) + - [Text Generation using Image File](#text-generation-using-image-file) + - [Text Generation using Image Data](#text-generation-using-image-data) + - [Chat Session (Multi-Turn Conversations)](#chat-session-multi-turn-conversations) + - [Tokens counting](#tokens-counting) + - [Listing models](#listing-models) + +## Installation + +> You need an API key to gain access to Google's Gemini API. +> Visit [Google AI Studio](https://makersuite.google.com/) to get an API key. + +First step is to install the Gemini API Client for Laravel with Composer. + +```shell +composer require gemini-api-php/laravel +``` + +## Configuration + +There are two ways to configure the client. + +### Environment variables + +You can set the `GEMINI_API_KEY` environment variable with the API key you obtained from Google AI studio. + +Add the following line into your `.env` file. + +```shell +GEMINI_API_KEY='YOUR_GEMINI_API_KEY' +``` + +### Configuration file + +You can also run the following command to create a configuration file in your applications config folder. + +```shell +php artisan vendor:publish --provider=GeminiAPI\Laravel\ServiceProvider +``` + +Now you can edit the `config/gemini.php` file to configure the Gemini API client. + +## How to use + +### Text Generation + +```php +use GeminiAPI\Laravel\Facades\Gemini; + +print Gemini::generateText('PHP in less than 100 chars'); +// PHP: A server-side scripting language used to create dynamic web applications. +// Easy to learn, widely used, and open-source. +``` + +### Text Generation Using Image File + +```php +use GeminiAPI\Laravel\Facades\Gemini; + +print Gemini::generateTextUsingImageFile( + 'image/jpeg', + 'elephpant.jpg', + 'Explain what is in the image', +); +// The image shows an elephant standing on the Earth. +// The elephant is made of metal and has a glowing symbol on its forehead. +// The Earth is surrounded by a network of glowing lines. +// The image is set against a starry background. +``` + +### Text Generation Using Image Data + +```php +use GeminiAPI\Laravel\Facades\Gemini; + +print Gemini::generateTextUsingImage( + 'image/jpeg', + base64_encode(file_get_contents('elephpant.jpg')), + 'Explain what is in the image', +); +// The image shows an elephant standing on the Earth. +// The elephant is made of metal and has a glowing symbol on its forehead. +// The Earth is surrounded by a network of glowing lines. +// The image is set against a starry background. +``` + +### Chat Session (Multi-Turn Conversations) + +```php +use GeminiAPI\Laravel\Facades\Gemini; + +$chat = Gemini::startChat(); + +print $chat->sendMessage('Hello World in PHP'); +// echo "Hello World!"; +// This code will print "Hello World!" to the standard output. + +print $chat->sendMessage('in Go'); +// fmt.Println("Hello World!") +// This code will print "Hello World!" to the standard output. +``` + +### Tokens counting + +```php +use GeminiAPI\Laravel\Facades\Gemini; + +print Gemini::countTokens('PHP in less than 100 chars'); +// 10 +``` + +### Listing models + +```php +use GeminiAPI\Laravel\Facades\Gemini; + +print_r(Gemini::listModels()); +//[ +// [0] => GeminiAPI\Resources\Model Object +// ( +// [name] => models/gemini-pro +// [displayName] => Gemini Pro +// [description] => The best model for scaling across a wide range of tasks +// ... +// ) +// [1] => GeminiAPI\Resources\Model Object +// ( +// [name] => models/gemini-pro-vision +// [displayName] => Gemini Pro Vision +// [description] => The best image understanding model to handle a broad range of applications +// ... +// ) +//] +``` diff --git a/assets/example.png b/assets/example.png new file mode 100644 index 0000000..0564848 Binary files /dev/null and b/assets/example.png differ diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..f5b36dc --- /dev/null +++ b/composer.json @@ -0,0 +1,78 @@ +{ + "name": "gemini-api-php/laravel", + "description": "Gemini API client for Laravel", + "keywords": [ + "laravel", + "php", + "client", + "sdk", + "api", + "google", + "gemini", + "gemini pro", + "gemini pro vision", + "ai" + ], + "license": "MIT", + "authors": [ + { + "name": "Erdem Köse", + "email": "erdemkose@gmail.com" + } + ], + "require": { + "php": "^8.1", + "gemini-api-php/client": "^1.1", + "illuminate/support": "^9.0 || ^10.0 || ^11.0", + "psr/container": "^1.0 || ^2.0", + "psr/http-client": "^1.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^7.8.1", + "guzzlehttp/psr7": "^2.0", + "laravel/framework": "^9.0 || ^10.0 || ^11.0", + "laravel/pint": "^1.13.6", + "pestphp/pest": "^2.27.0", + "pestphp/pest-plugin-arch": "^2.4.1", + "phpstan/phpstan": "^1.10.47", + "symfony/var-dumper": "^6.4.0|^7.0.1" + }, + "autoload": { + "psr-4": { + "GeminiAPI\\Laravel\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "GeminiAPI\\Laravel\\Tests\\": "tests" + } + }, + "minimum-stability": "dev", + "prefer-stable": true, + "config": { + "sort-packages": true, + "preferred-install": "dist", + "allow-plugins": { + "php-http/discovery": true, + "pestphp/pest-plugin": true + } + }, + "extra": { + "laravel": { + "providers": [ + "GeminiAPI\\Laravel\\ServiceProvider" + ] + } + }, + "scripts": { + "lint": "pint -v", + "test:lint": "pint --test -v", + "test:types": "phpstan analyse --ansi", + "test:unit": "pest --colors=always", + "test": [ + "@test:lint", + "@test:types", + "@test:unit" + ] + } +} diff --git a/config/gemini.php b/config/gemini.php new file mode 100644 index 0000000..8cab295 --- /dev/null +++ b/config/gemini.php @@ -0,0 +1,21 @@ + env('GEMINI_API_KEY'), + + /** + * Gemini Base URL + * + * If you need a specific base URL for the Gemini API, you can provide it here. + * Otherwise, leave empty to use the default value. + */ + 'base_url' => env('GEMINI_BASE_URL'), +]; diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..7ab41e4 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,7 @@ +parameters: + level: max + paths: + - src + - config + treatPhpDocTypesAsCertain: false + reportUnmatchedIgnoredErrors: true diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..c93d169 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,28 @@ + +