Skip to content

feat: add Application resource support#158

Draft
devin-ai-integration[bot] wants to merge 11 commits into
mainfrom
cdrappier/app-runtime
Draft

feat: add Application resource support#158
devin-ai-integration[bot] wants to merge 11 commits into
mainfrom
cdrappier/app-runtime

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Fixes ENG-2932

Summary

Adds ApplicationInstance and SyncApplicationInstance CRUD helpers for the new Application resource, following the same pattern as DriveInstance/VolumeInstance.

Step 1 – Client regeneration: Regenerated the controlplane client from the cdrappier/application-runtime-pr2-api branch spec. This pulls in Application, ApplicationSpec, ApplicationList models and create/get/list/delete/update_application + list_application_revisions API functions, plus other new models from the updated spec (pagination, firewall, HIPAA, etc.).

Step 2 – Application helper (src/blaxel/core/application/):

# Async
app = await ApplicationInstance.create({"name": "my-app", "region": "us-pdx-1"})
app = await ApplicationInstance.get("my-app")
apps = await ApplicationInstance.list()
await app.delete()
app = await app.update({"display_name": "New Name"})
app = await ApplicationInstance.create_if_not_exists({...})

# Sync
app = SyncApplicationInstance.create({"name": "my-app", "region": "us-pdx-1"})

Key design choices:

  • ApplicationCreateConfiguration accepts name, display_name, labels, image, region, enabled
  • list() handles the paginated ApplicationList response (extracts .data)
  • Delete/update use the same descriptor pattern (_AsyncDeleteDescriptor / _SyncUpdateDescriptor) for class-level and instance-level calls
  • Region warning matches Drive/Volume behavior

Step 3 – Exports: Re-exported ApplicationInstance, SyncApplicationInstance, ApplicationCreateConfiguration, ApplicationAPIError from blaxel.core.

Link to Devin session: https://app.devin.ai/sessions/7bcfb61fc2a0401587b0faa456cbe08d
Requested by: @drappier-charles


Note

Adds ApplicationInstance and SyncApplicationInstance CRUD helpers for the new Application resource, regenerates the controlplane client with new models (ApplicationExtension, ChangelogEntry, SandboxFork/Snapshot, CustomDomainSpecDomainType, etc.), and fixes the previously-flagged duplicate allowed_domains block in proxy_config.py.

Written by Mendral for commit 7b40792.

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@mendral-app

mendral-app Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

✅ Linked to Linear issue ENG-2932 — status set to In Progress

  • Assignee: Charles Drappier (@drappier-charles)
  • Match: This PR implements exactly the Python SDK regeneration + ApplicationInstance DX helpers described in ENG-2932
  • PR linked: ✅ Issue will auto-close when this PR merges

Linear reference Fixes ENG-2932 prepended to PR description.

Note

Posted by Linear Issue Enforcer · Tag @mendral-app with feedback.

@mendral-app

mendral-app Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

🔀 Component Interaction Diagram

Here's a sequence diagram showing the key interactions introduced by this PR:

sequenceDiagram
    participant User as User Code
    participant AI as ApplicationInstance<br/>(Async/Sync)
    participant Config as ApplicationCreate<br/>Configuration
    participant API as API Endpoint Functions<br/>(create/get/list/update/delete)
    participant HTTP as HTTPX Client
    participant CP as Controlplane API

    Note over User, CP: CREATE Flow
    User->>AI: ApplicationInstance.create(config)
    AI->>Config: Normalize input (dict/config/Application)
    Config-->>AI: ApplicationCreateConfiguration
    AI->>AI: Build Application model (Metadata + ApplicationSpec)
    AI->>API: create_application(client, body)
    API->>HTTP: POST /applications
    HTTP->>CP: HTTP Request
    CP-->>HTTP: 200 Application / 409 Error
    HTTP-->>API: Response
    API-->>AI: Application or Error
    AI-->>User: ApplicationInstance (wrapped)

    Note over User, CP: GET Flow
    User->>AI: ApplicationInstance.get(name)
    AI->>API: get_application(name, client)
    API->>HTTP: GET /applications/{name}
    HTTP->>CP: HTTP Request
    CP-->>HTTP: 200 Application / 404 Error
    API-->>AI: Application or Error
    AI-->>User: ApplicationInstance (wrapped)

    Note over User, CP: UPDATE Flow (via Descriptor)
    User->>AI: instance.update(changes)
    AI->>AI: _AsyncUpdateDescriptor.__get__()
    AI->>API: get_application (fetch current state)
    API->>HTTP: GET /applications/{name}
    HTTP-->>API: Current Application
    AI->>AI: Merge changes with current state
    AI->>API: update_application(name, client, merged_body)
    API->>HTTP: PUT /applications/{name}
    HTTP->>CP: HTTP Request
    CP-->>API: Updated Application
    API-->>AI: Application
    AI-->>User: New ApplicationInstance

    Note over User, CP: CREATE_IF_NOT_EXISTS Flow
    User->>AI: ApplicationInstance.create_if_not_exists(config)
    AI->>API: create_application(client, body)
    API->>HTTP: POST /applications
    HTTP->>CP: HTTP Request
    alt Success (200)
        CP-->>AI: Application
        AI-->>User: ApplicationInstance
    else Conflict (409)
        CP-->>AI: Error (APPLICATION_ALREADY_EXISTS)
        AI->>API: get_application(name, client)
        API->>HTTP: GET /applications/{name}
        CP-->>AI: Existing Application
        AI-->>User: ApplicationInstance (existing)
    end
Loading

Summary of the Flow

This PR adds full CRUD support for the Application resource, following the existing SDK patterns (similar to DriveInstance/VolumeInstance):

Layer Role
ApplicationInstance / SyncApplicationInstance Public-facing wrapper with convenience properties and classmethods
ApplicationCreateConfiguration Normalizes user input (dict, config, or raw model) into a valid Application object
API Endpoint Functions Generated from OpenAPI spec — handles HTTP request building and response parsing
HTTPX Client Executes HTTP calls against the Controlplane API

Key design choices:

  • Descriptor pattern for delete/update — enables both Class.method(name) and instance.method() usage
  • Merge-on-update — fetches current state before applying partial updates to avoid field loss
  • Dual async/sync — consistent interface for both execution models
  • Auto-generated names — defaults to app-{uuid[:8]} if no name is provided

Note

Posted by PR Sequence Diagram · Tag @mendral-app with feedback.

@mendral-app

mendral-app Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

🧪 Testing Guide

What this PR addresses

Adds full Application resource lifecycle management to the SDK via new ApplicationInstance and SyncApplicationInstance CRUD helper classes (following the existing DriveInstance/VolumeInstance pattern). Also includes client regeneration from a new API spec, adding sandbox snapshot/fork operations, drive/volume lookup by external ID, changelog API, and several new models.

Steps to exercise the new behavior

  1. Import and instantiate (async):

    from blaxel.core import ApplicationInstance, ApplicationCreateConfiguration
    
    # Create
    app = await ApplicationInstance.create(ApplicationCreateConfiguration(
        display_name="my-test-app",
        region="us-east-1",
    ))
    
    # Get
    app = await ApplicationInstance.get("my-test-app-uuid")
    
    # List
    apps = await ApplicationInstance.list()
    
    # Update
    await app.update({"display_name": "renamed-app"})
    
    # Delete
    await app.delete()
    
    # Idempotent create
    app = await ApplicationInstance.create_if_not_exists(config)
  2. Import and instantiate (sync):

    from blaxel.core import SyncApplicationInstance, ApplicationCreateConfiguration
    
    app = SyncApplicationInstance.create(ApplicationCreateConfiguration(
        display_name="my-test-app",
        region="us-east-1",
    ))
  3. Error handling:

    from blaxel.core import ApplicationAPIError
    
    try:
        await ApplicationInstance.get("nonexistent")
    except ApplicationAPIError as e:
        print(e)  # Should surface 404 properly
  4. Verify new API functions work (sandbox snapshots, fork, external ID lookups) by calling the generated client functions directly if a control plane is available.

What to verify (expected behavior)

  • ApplicationInstance and SyncApplicationInstance expose create, get, list, create_if_not_exists, update, and delete — mirroring the DriveInstance pattern exactly.
  • create auto-generates a UUID-based name when none is provided, and emits a FutureWarning if region is not specified.
  • create_if_not_exists gracefully handles HTTP 409 (conflict) by returning the existing instance.
  • get raises ApplicationAPIError on 404.
  • update merges the provided config with the current state before calling the API.
  • Properties (metadata, spec, status, events, name, display_name) are accessible on returned instances.
  • All new models (Application, ApplicationSpec, AppRevision, sandbox-related models, etc.) import cleanly from blaxel.core.client.models.
  • list_application_revisions now returns AppRevision instead of RevisionMetadata.
  • Existing tests continue to pass with no regressions to drives/volumes.
  • The package imports (from blaxel.core import ...) include the four new exports: ApplicationInstance, SyncApplicationInstance, ApplicationCreateConfiguration, ApplicationAPIError.

Note

Posted by PR Testing Guide · Tag @mendral-app with feedback.

mendral-app[bot]

This comment was marked as outdated.

mendral-app[bot]

This comment was marked as outdated.

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Devin is archived and cannot be woken up. Please unarchive Devin if you want to continue using it.

1 similar comment
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Devin is archived and cannot be woken up. Please unarchive Devin if you want to continue using it.

mendral-app[bot]

This comment was marked as outdated.

mendral-app[bot]

This comment was marked as outdated.

drappier-charles and others added 4 commits July 1, 2026 20:34
- Regenerate controlplane client from cdrappier/application-runtime-pr2-api branch spec
- Add Application models (Application, ApplicationSpec, ApplicationList) and API functions (CRUD + list revisions)
- Create ApplicationInstance (async) and SyncApplicationInstance (sync) helper classes
- Support create, get, list, delete, update, and create_if_not_exists operations
- Export from blaxel.core.application and re-export from blaxel.core

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Check for Error responses in _delete_application_by_name and
_delete_application_by_name_sync, raising ApplicationAPIError
instead of silently returning Error typed as Application.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…plication-runtime-pr3-app

Regenerated SDK with latest OpenAPI definitions including:
- Application resource endpoints (CRUD + list revisions)
- Sandbox fork/snapshot endpoints
- Updated list models with cursor pagination fields

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… spec

Regenerated the auto-generated API client (api/ and models/) from the
latest controlplane feature/app-runtime branch OpenAPI spec. Includes
new Application, Snapshot, Fork, Schedule, DrivePermission, and
CustomDomain types.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration
devin-ai-integration Bot force-pushed the cdrappier/app-runtime branch from aa4559e to 1073527 Compare July 1, 2026 20:36
mendral-app[bot]

This comment was marked as outdated.

drappier-charles and others added 5 commits July 13, 2026 23:17
- Regenerate controlplane client from cdrappier/application-runtime-pr2-api branch spec
- Add Application models (Application, ApplicationSpec, ApplicationList) and API functions (CRUD + list revisions)
- Create ApplicationInstance (async) and SyncApplicationInstance (sync) helper classes
- Support create, get, list, delete, update, and create_if_not_exists operations
- Export from blaxel.core.application and re-export from blaxel.core

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Check for Error responses in _delete_application_by_name and
_delete_application_by_name_sync, raising ApplicationAPIError
instead of silently returning Error typed as Application.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…plication-runtime-pr3-app

Regenerated SDK with latest OpenAPI definitions including:
- Application resource endpoints (CRUD + list revisions)
- Sandbox fork/snapshot endpoints
- Updated list models with cursor pagination fields

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… spec

Regenerated the auto-generated API client (api/ and models/) from the
latest controlplane feature/app-runtime branch OpenAPI spec. Includes
new Application, Snapshot, Fork, Schedule, DrivePermission, and
CustomDomain types.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration
devin-ai-integration Bot force-pushed the cdrappier/app-runtime branch from 1073527 to 556cf3b Compare July 13, 2026 23:19
mendral-app[bot]

This comment was marked as outdated.

mendral-app[bot]

This comment was marked as outdated.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

@mendral-app mendral-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

The previous review comment about the duplicate allowed_domains block in proxy_config.py has been fixed in 7b40792. The application helper logic is correct — the enabled is not None guard properly distinguishes "not specified" from "explicitly set to False" in the update merge. The remaining changes are standard auto-generated client code additions.

Tag @mendral-app with feedback or questions. View session

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant