Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Pyrus Client Symfony Laravel Package

suare-su/pyrus_client_symfony

Symfony integration for the Pyrus client, making it easy to connect Symfony applications to Pyrus services through a configurable bundle. Provides the glue for using Pyrus APIs within your Symfony project.

View on GitHub
Deep Wiki
Context7

Getting Started

suare-su/pyrus_client_symfony is a Symfony-bundle-flavored client for the Pyrus API (tasks, comments, catalogs, forms). It has no Laravel service provider, so plan on ~15 minutes of wiring before your first call.

  1. Install the dependency

    composer require suare-su/pyrus_client_symfony
    

    Pin the minor version (^0.16) — this is still pre-1.0 and method signatures have moved between releases.

  2. Add credentials to config. Put Pyrus credentials in config/services.php rather than reading env() at call sites:

    'pyrus' => [
        'base_url' => env('PYRUS_URL', 'https://api.pyrus.com/v4'),
        'login'    => env('PYRUS_LOGIN'),      // account e-mail
        'key'      => env('PYRUS_SECURITY_KEY'),
        'timeout'  => 10,
    ],
    
  3. Register the client in a service provider. The bundle's DI extension won't run inside Laravel, so instantiate the client yourself in AppServiceProvider::register() and bind it as a singleton. Wrap it in a thin App\Support\Pyrus\PyrusClient adapter so the rest of your app never imports package namespaces — this is what makes the next 0.x upgrade cheap.

  4. Look here first: the package's Client/Api class and the *Create / *Get request objects. The README examples are Symfony-console-shaped; translate them into the adapter. The tests/ directory is the most reliable documentation of the actual payload shapes.

  5. First use case: post a comment onto an existing Pyrus task — the subject of this release. Given a task ID (stored on your Eloquent model), build a CommentCreate request with the comment body and dispatch it. That single call unlocks the most common Laravel↔Pyrus integration: pushing status from your app into the task thread where business users actually read it.

    $client->comments()->create(
        CommentCreate::make($order->pyrus_task_id)->text("Shipped: {$order->tracking_number}")
    );
    

Implementation Patterns

Outbound notification (most common). Map Laravel domain events to Pyrus comments via a queued listener. Because CommentCreate is now a first-class request object, the listener stays declarative:

class CommentOnPyrusTask implements ShouldQueue
{
    public function handle(OrderShipped $event): void
    {
        $this->pyrus->comments()->create(
            CommentCreate::make($event->order->pyrus_task_id)
                ->text(view('pyrus.shipped', ['order' => $event->order])->render())
        );
    }
}

Keep the HTTP call out of the request cycle — Pyrus latency should never block a user action or an HTTP response.

Wrap, don't sprinkle. Expose your own interface (PyrusGateway) with the 5–6 operations you actually use (create comment, get task, list catalog, upload file, create task). Bind the package behind it. When the package reorganizes namespaces in 0.17, you patch one file.

Idempotency guard. Pyrus has no idempotency key on comment creation. Add a pyrus_comments table keyed by (model_type, model_id, event) and skip if a row exists; this also gives you an audit trail and a replay path after failed jobs.

Throttling. Route all Pyrus traffic through a named queue with RateLimited middleware (RateLimiter::for('pyrus', fn () => Limit::perSecond(3))). Comment bursts from a bulk import will otherwise 429, and the Symfony transport will surface that as a generic exception.

Testing. Http::fake() does nothing here — the package uses Symfony HttpClient, not the Laravel HTTP client. Test your own gateway interface with a fake implementation, and if you must test the adapter, inject Symfony\Component\HttpClient\MockHttpClient and assert on the recorded request body. Never let CI touch the real API.

Formatting comments. Business users read these in the Pyrus UI, so render a Blade view to a string rather than concatenating text — but keep the result plain-ish; Pyrus comment markup is not HTML.

Gotchas and Tips

  • Exceptions aren't Laravel's. Failures throw Symfony\Contracts\HttpClient\Exception\* (ClientExceptionInterface, TransportExceptionInterface), not Illuminate\Http\Client\RequestException. Catch those types explicitly, and let TransportExceptionInterface retry while treating 4xx as terminal.
  • Config is not auto-discovered. There is no bundle extension in Laravel and no config/pyrus.php to publish. If you copy a bundle config array anywhere, it will be silently ignored — construct the client with explicit arguments and test that the base URL and credentials actually land.
  • Auth failures look like 401s on every call. Double-check you are sending the security key (API key), not the user password, and that the login is the e-mail the key was issued to. Cache a "credentials valid" check in a health command so a rotated key fails loudly at deploy time, not silently in a queue.
  • Write operations are not retroactive-safe. A retried job that already succeeded posts a duplicate comment on the task. Set tries = 1 plus your idempotency table, or make the comment body carry a dedupe marker you can detect before retrying.
  • Logging leaks keys. Symfony's HTTP client debug output and exception messages can include request headers. Scrub PYRUS_SECURITY_KEY in any exception reporter before it reaches Sentry/Bugsnag.
  • Timeouts default high. Set an explicit timeout (5–10s) and a short max_duration for retries; otherwise a hung connection occupies a queue worker for minutes.
  • Version pinning is non-negotiable. At 0.x, CommentCreate's constructor/method names may change in a patch. Use "suare-su/pyrus_client_symfony": "~0.16.0" and read the changelog before bumping — this release itself is a pure addition, but there's no BC promise yet.
  • Extension point: if you need approvals or form-field values on a comment, check whether CommentCreate exposes them; if not, subclass your adapter's request builder rather than forking the package — you want to stay on the upstream upgrade path for when those land.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin