{"id":14983869,"url":"https://github.com/google-gemini-php/symfony","last_synced_at":"2025-04-10T19:41:20.432Z","repository":{"id":222245212,"uuid":"756692478","full_name":"google-gemini-php/symfony","owner":"google-gemini-php","description":"⚡️ Gemini PHP for Symfony is a community-maintained PHP API client that allows you to interact with the Gemini AI API.","archived":false,"fork":false,"pushed_at":"2024-02-17T09:31:51.000Z","size":42,"stargazers_count":11,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-03T07:23:24.074Z","etag":null,"topics":["gemini","gemini-api","google","google-ai","google-ai-platform","symfony","symfony-bundle"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/google-gemini-php.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-13T05:44:41.000Z","updated_at":"2024-12-28T06:18:54.000Z","dependencies_parsed_at":"2024-10-13T06:20:35.498Z","dependency_job_id":null,"html_url":"https://github.com/google-gemini-php/symfony","commit_stats":{"total_commits":3,"total_committers":1,"mean_commits":3.0,"dds":0.0,"last_synced_commit":"64595aa8488acf2b8660fafaf8d2337e38416cf6"},"previous_names":["google-gemini-php/symfony"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/google-gemini-php%2Fsymfony","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/google-gemini-php%2Fsymfony/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/google-gemini-php%2Fsymfony/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/google-gemini-php%2Fsymfony/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/google-gemini-php","download_url":"https://codeload.github.com/google-gemini-php/symfony/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239370688,"owners_count":19627472,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gemini","gemini-api","google","google-ai","google-ai-platform","symfony","symfony-bundle"],"created_at":"2024-09-24T14:08:05.887Z","updated_at":"2025-02-17T21:32:46.062Z","avatar_url":"https://github.com/google-gemini-php.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/google-gemini-php/symfony/main/art/example.png\" width=\"600\" alt=\"Google Gemini PHP for Symfony\"\u003e\n    \u003cp align=\"center\"\u003e\n        \u003ca href=\"https://packagist.org/packages/google-gemini-php/symfony\"\u003e\u003cimg alt=\"Latest Version\" src=\"https://img.shields.io/packagist/v/google-gemini-php/symfony\"\u003e\u003c/a\u003e\n        \u003ca href=\"https://packagist.org/packages/google-gemini-php/symfony\"\u003e\u003cimg alt=\"License\" src=\"https://img.shields.io/github/license/google-gemini-php/symfony\"\u003e\u003c/a\u003e\n    \u003c/p\u003e\n\u003c/p\u003e\n\n------\n\n**Gemini PHP** for Symfony is a community-maintained PHP API client that allows you to interact with the Gemini AI API.\n\n- Fatih AYDIN [github.com/aydinfatih](https://github.com/aydinfatih)\n\nFor more information, take a look at the [google-gemini-php/client](https://github.com/google-gemini-php/client) repository.\n\n## Table of Contents\n- [Prerequisites](#prerequisites)\n- [Setup](#setup)\n    - [Installation](#installation)\n    - [Setup your API key](#setup-your-api-key)\n- [Usage](#usage)\n    - [Chat Resource](#chat-resource)\n        - [Text-only Input](#text-only-input)\n        - [Text-and-image Input](#text-and-image-input)\n        - [Multi-turn Conversations (Chat)](#multi-turn-conversations-chat)\n        - [Stream Generate Content](#stream-generate-content)\n        - [Count tokens](#count-tokens)\n        - [Configuration](#configuration)\n    - [Embedding Resource](#embedding-resource)\n    - [Models](#models)\n        - [List Models](#list-models)\n        - [Get Model](#get-model)\n- [Testing](#testing)\n\n\n## Prerequisites\nTo complete this quickstart, make sure that your development environment meets the following requirements:\n\n- Requires [PHP 8.1+](https://php.net/releases/)\n- Requires [Symfony 5,6,7](https://symfony.com/)\n\n## Setup\n\n### Installation\n\nFirst, install Gemini via the [Composer](https://getcomposer.org/) package manager:\n\n```bash\ncomposer require google-gemini-php/symfony\n```\n\nNext, register the bundle in your config/bundles.php:\n\n```bash\nreturn [\n    // ...\n    Gemini\\Symfony\\GeminiBundle::class =\u003e ['all' =\u003e true],\n]\n```\n\nThis will create a .env configuration file in your project, which you can modify to your needs using environment variables:\n\n```\nGEMINI_API_KEY=\n```\n\nYou can also define the following environment variables.\n```\nGEMINI_BASE_URL=\n```\n\n\n### Setup your API key\nTo use the Gemini API, you'll need an API key. If you don't already have one, create a key in Google AI Studio.\n\n[Get an API key](https://makersuite.google.com/app/apikey)\n\n## Usage\n\nInteract with Gemini's API:\n\n```php\n$result = $container-\u003eget('gemini')-\u003egeminiPro()-\u003egenerateContent('Hello');\n\n$result-\u003etext(); // Hello! How can I assist you today?\n```\n\n### Chat Resource\n\n#### Text-only Input\nGenerate a response from the model given an input message. If the input contains only text, use the `gemini-pro` model.\n\n```php\n$result = $container-\u003eget('gemini')-\u003egeminiPro()-\u003egenerateContent('Hello');\n\n$result-\u003etext(); // Hello! How can I assist you today?\n```\n\n#### Text-and-image Input\nIf the input contains both text and image, use the `gemini-pro-vision` model.\n\n```php\n\n$result = $container-\u003eget('gemini')-\u003egeminiProVision()\n -\u003egenerateContent([\n  'What is this picture?',\n  new Blob(\n   mimeType: MimeType::IMAGE_JPEG,\n   data: base64_encode(\n    file_get_contents('https://storage.googleapis.com/generativeai-downloads/images/scones.jpg')\n   )\n  )\n ]);\n \n$result-\u003etext(); //  The picture shows a table with a white tablecloth. On the table are two cups of coffee, a bowl of blueberries, a silver spoon, and some flowers. There are also some blueberry scones on the table.\n```\n#### Multi-turn Conversations (Chat)\nUsing Gemini, you can build freeform conversations across multiple turns.\n\n```php\n$chat = $container-\u003eget('gemini')-\u003echat()\n -\u003estartChat(history: [\n   Content::parse(part: 'The stories you write about what I have to say should be one line. Is that clear?'),\n   Content::parse(part: 'Yes, I understand. The stories I write about your input should be one line long.', role: Role::MODEL)\n ]);\n\n$response = $chat-\u003esendMessage('Create a story set in a quiet village in 1600s France');\necho $response-\u003etext(); // Amidst rolling hills and winding cobblestone streets, the tranquil village of Beausoleil whispered tales of love, intrigue, and the magic of everyday life in 17th century France.\n\n$response = $chat-\u003esendMessage('Rewrite the same story in 1600s England');\necho $response-\u003etext(); // In the heart of England's lush countryside, amidst emerald fields and thatched-roof cottages, the village of Willowbrook unfolded a tapestry of love, mystery, and the enchantment of ordinary days in the 17th century.\n\n```\n\u003eThe `gemini-pro-vision` model (for text-and-image input) is not yet optimized for multi-turn conversations. Make sure to use gemini-pro and text-only input for chat use cases.\n\n#### Stream Generate Content\nBy default, the model returns a response after completing the entire generation process. You can achieve faster interactions by not waiting for the entire result, and instead use streaming to handle partial results.\n\n```php\n$stream = $container-\u003eget('gemini')-\u003egeminiPro()\n -\u003estreamGenerateContent('Write long a story about a magic backpack.');\n\nforeach ($stream as $response) {\n echo $response-\u003etext();\n}\n```\n\n#### Count tokens\nWhen using long prompts, it might be useful to count tokens before sending any content to the model.\n\n```php\n$response = $container-\u003eget('gemini')-\u003egeminiPro()\n -\u003ecountTokens('Write a story about a magic backpack.');\n\necho $response-\u003etotalTokens; // 9\n```\n\n#### Configuration\nEvery prompt you send to the model includes parameter values that control how the model generates a response. The model can generate different results for different parameter values. Learn more about [model parameters](https://ai.google.dev/docs/concepts#model_parameters).\n\nAlso, you can use safety settings to adjust the likelihood of getting responses that may be considered harmful. By default, safety settings block content with medium and/or high probability of being unsafe content across all dimensions. Learn more about [safety settings](https://ai.google.dev/docs/concepts#safety_setting).\n\n\n```php\nuse Gemini\\Data\\GenerationConfig;\nuse Gemini\\Enums\\HarmBlockThreshold;\nuse Gemini\\Data\\SafetySetting;\nuse Gemini\\Enums\\HarmCategory;\n\n$safetySettingDangerousContent = new SafetySetting(\n    category: HarmCategory::HARM_CATEGORY_DANGEROUS_CONTENT,\n    threshold: HarmBlockThreshold::BLOCK_ONLY_HIGH\n);\n\n$safetySettingHateSpeech = new SafetySetting(\n    category: HarmCategory::HARM_CATEGORY_HATE_SPEECH,\n    threshold: HarmBlockThreshold::BLOCK_ONLY_HIGH\n);\n\n$generationConfig = new GenerationConfig(\n    stopSequences: [\n        'Title',\n    ],\n    maxOutputTokens: 800,\n    temperature: 1,\n    topP: 0.8,\n    topK: 10\n);\n\n$generativeModel = $container-\u003eget('gemini')-\u003egeminiPro()\n -\u003ewithSafetySetting($safetySettingDangerousContent)\n -\u003ewithSafetySetting($safetySettingHateSpeech)\n -\u003ewithGenerationConfig($generationConfig)\n -\u003egenerateContent(\"Write a story about a magic backpack.\");\n```\n\n### Embedding Resource\nEmbedding is a technique used to represent information as a list of floating point numbers in an array. With Gemini, you can represent text (words, sentences, and blocks of text) in a vectorized form, making it easier to compare and contrast embeddings. For example, two texts that share a similar subject matter or sentiment should have similar embeddings, which can be identified through mathematical comparison techniques such as cosine similarity.\n\nUse the `embedding-001` model with either `embedContents` or `batchEmbedContents`:\n\n```php\n$response = $container-\u003eget('gemini')-\u003eembeddingModel()\n -\u003eembedContent(\"Write a story about a magic backpack.\");\n\nprint_r($response-\u003eembedding-\u003evalues);\n//[\n//    [0] =\u003e 0.008624583\n//    [1] =\u003e -0.030451821\n//    [2] =\u003e -0.042496547\n//    [3] =\u003e -0.029230341\n//    [4] =\u003e 0.05486475\n//    [5] =\u003e 0.006694871\n//    [6] =\u003e 0.004025645\n//    [7] =\u003e -0.007294857\n//    [8] =\u003e 0.0057651913\n//    ...\n//]\n```\n\n### Models\n\n#### List Models\nUse list models to see the available Gemini models:\n\n```php\n$response = $container-\u003eget('gemini')-\u003emodels()-\u003elist();\n\n$response-\u003emodels;\n//[\n//    [0] =\u003e Gemini\\Data\\Model Object\n//        (\n//            [name] =\u003e models/gemini-pro\n//            [version] =\u003e 001\n//            [displayName] =\u003e Gemini Pro\n//            [description] =\u003e The best model for scaling across a wide range of tasks\n//            ...\n//        )\n//    [1] =\u003e Gemini\\Data\\Model Object\n//        (\n//            [name] =\u003e models/gemini-pro-vision\n//            [version] =\u003e 001\n//            [displayName] =\u003e Gemini Pro Vision\n//            [description] =\u003e The best image understanding model to handle a broad range of applications\n//            ...\n//        )\n//    [2] =\u003e Gemini\\Data\\Model Object\n//        (\n//            [name] =\u003e models/embedding-001\n//            [version] =\u003e 001\n//            [displayName] =\u003e Embedding 001\n//            [description] =\u003e Obtain a distributed representation of a text.\n//            ...\n//        )\n//]\n```\n\n#### Get Model\nGet information about a model, such as version, display name, input token limit, etc.\n```php\n\n$response = $container-\u003eget('gemini')-\u003emodels()-\u003eretrieve(ModelType::GEMINI_PRO);\n\n$response-\u003emodel;\n//Gemini\\Data\\Model Object\n//(\n//    [name] =\u003e models/gemini-pro\n//    [version] =\u003e 001\n//    [displayName] =\u003e Gemini Pro\n//    [description] =\u003e The best model for scaling across a wide range of tasks\n//    ...\n//)\n```\n\n## Testing\n\nThe package provides a fake implementation of the `Gemini\\Client` class that allows you to fake the API responses.\n\nTo test your code ensure you swap the `Gemini\\Client` class with the `Gemini\\Testing\\ClientFake` class in your test case.\n\nThe fake responses are returned in the order they are provided while creating the fake client.\n\nAll responses are having a `fake()` method that allows you to easily create a response object by only providing the parameters relevant for your test case.\n\n```php\nuse Gemini\\Testing\\ClientFake;\nuse Gemini\\Responses\\GenerativeModel\\GenerateContentResponse;\n\n$container-\u003eget('gemini')-\u003efake([\n  GenerateContentResponse::fake([\n    'candidates' =\u003e [\n      [\n        'content' =\u003e [\n          'parts' =\u003e [\n            [\n              'text' =\u003e 'success',\n            ],\n          ],\n        ],\n      ],\n    ],\n  ]),\n]);\n\n$result = $container-\u003eget('gemini')-\u003egeminiPro()-\u003egenerateContent('test');\n\nexpect($result-\u003etext())-\u003etoBe('success');\n```\n\nIn case of a streamed response you can optionally provide a resource holding the fake response data.\n\n```php\nuse Gemini\\Testing\\ClientFake;\nuse Gemini\\Responses\\GenerativeModel\\GenerateContentResponse;\n\n$container-\u003eget('gemini')-\u003efake([\n    GenerateContentResponse::fakeStream(),\n]);\n\n$result = $container-\u003eget('gemini')-\u003egeminiPro()-\u003estreamGenerateContent('Hello');\n\nexpect($response-\u003egetIterator()-\u003ecurrent())\n    -\u003etext()-\u003etoBe('In the bustling city of Aethelwood, where the cobblestone streets whispered');\n```\n\nAfter the requests have been sent there are various methods to ensure that the expected requests were sent:\n\n```php\n// assert list models request was sent\n$container-\u003eget('gemini')-\u003emodels()-\u003eassertSent(callback: function ($method) {\n    return $method === 'list';\n});\n// or\n$container-\u003eget('gemini')-\u003eassertSent(resource: Models::class, callback: function ($method) {\n    return $method === 'list';\n});\n\n$container-\u003eget('gemini')-\u003egeminiPro()-\u003eassertSent(function (string $method, array $parameters) {\n    return $method === 'generateContent' \u0026\u0026\n        $parameters[0] === 'Hello';\n});\n// or\n$container-\u003eget('gemini')-\u003eassertSent(resource: GenerativeModel::class, model: ModelType::GEMINI_PRO, callback: function (string $method, array $parameters) {\n    return $method === 'generateContent' \u0026\u0026\n        $parameters[0] === 'Hello';\n});\n\n\n// assert 2 generative model requests were sent\n$container-\u003eget('gemini')-\u003eassertSent(resource: GenerativeModel::class, model: ModelType::GEMINI_PRO, callback: 2);\n// or\n$container-\u003eget('gemini')-\u003egeminiPro()-\u003eassertSent(2);\n\n// assert no generative model requests were sent\n$container-\u003eget('gemini')-\u003eassertNotSent(resource: GenerativeModel::class, model: ModelType::GEMINI_PRO);\n// or\n$container-\u003eget('gemini')-\u003egeminiPro()-\u003eassertNotSent();\n\n// assert no requests were sent\n$container-\u003eget('gemini')-\u003eassertNothingSent();\n```\n\nTo write tests expecting the API request to fail you can provide a `Throwable` object as the response.\n\n```php\n$container-\u003eget('gemini')-\u003efake([\n    new ErrorException([\n        'message' =\u003e 'The model `gemini-basic` does not exist',\n        'status' =\u003e 'INVALID_ARGUMENT',\n        'code' =\u003e 400,\n    ]),\n]);\n\n// the `ErrorException` will be thrown\n$container-\u003eget('gemini')-\u003egeminiPro()-\u003egenerateContent('test');\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoogle-gemini-php%2Fsymfony","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgoogle-gemini-php%2Fsymfony","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoogle-gemini-php%2Fsymfony/lists"}