Skip to main content

No project description provided

Project description

python-admin-sdk

Install

pip install pluginlab_admin

Getting started

Get started by initializing the Pluginlab app:

from pluginlab_admin import App

app = App(
    secret_key="<PLUGIN_SECRET>",
    plugin_id="<PLUGIN_ID>",
)

# to manage auth-related stuff, mostly members
auth = app.get_auth()

The SDK secret should be generated from your Pluginlab dashboard.

Verify the user token

Everytime ChatGPT will talk to your backend through the PluginLab proxy, it will send the user token in the Authorization header as a bearer token. You can verify the integrity of such token by using the verify_token method:

auth = app.get_auth()

# usually you'd get the token from the Authorization header of the HTTP request, formatted as `Bearer <token>`
token = "eyJhbGc...dQssw5c"

try:
    payload = auth.verify_token(token)
    # from that point we know the information in the token hasn't been tampered with

    # we could, for instance, check if the user has a given plan and take specific action based on that
    premium_plan_id = 'KWsmKyJnHBF2Dz1mETDF'
    plan_id = payload.user.plan_id

    if plan_id:
        if plan_id == premium_plan_id: 
            do_something_special()
        else
            do_other_stuff()

    print(payload.uid)
except Exception as e:
    print(f"An error occurred while verifying the token: {e}")

The verified token payload is represented by the following typings:

class TokenPayloadUser:
    id: str
    email: str
    name: Optional[str] = None
    given_name: Optional[str] = None
    plan_id: Optional[str] = None
    price_id: Optional[str] = None

class TokenPayload:
    uid: str
    iss: str
    aud: str
    iat: int
    exp: int
    user: TokenPayloadUser

Get a member by id or email

By email

member = auth.get_member_by_email('johndoe@example.com')

if member is None:
    print('No such member.')
else
    print(f'Member with email {member.auth.email} signed up with method "{member.auth.sign_in_method}"')

By id

member = auth.get_member_by_id('mem_ec9fd884f7fc81fc9e5576d213b6e826d3109d26')

if member is None:
    print('No such member.')
else
    print(f'Member with id {member.id} (email={member.auth.email}) signed up with method "{member.auth.sign_in_method}"')

A member is represented with the following typings:

class SignInMethodId(Enum):
    EMAIL_AND_PASSWORD = 'email-and-password'
    MAGIC_EMAIL_CODE = 'magic-email-code'
    GOOGLE = 'google'

class MemberAuth:
    is_verified: bool;
    email: str;
    has_password: bool;
    sign_in_method: SignInMethodId;

class Member:
    id: str;
    auth: MemberAuth;
    name: Optional[str]
    given_name: Optional[str]
    family_name: Optional[str]
    picture_url: Optional[str]
    custom_fields: dict[str, str];
    metadata: dict[str, str];
    created_at_ms: int;
    updated_at_ms: int;

Get member identities

Once a user logs in to your PluginLab portal using a third-party authentication provider, they get assigned an identity for that specific provider. An identity might contain what you need to interact with the service on behalf of your user such as an access token or a refresh token. To retrieve all the identities for a given user, use the auth.get_member_identities method:

identities = auth.get_member_identities("mem_66c72702dfd9c9a34e80cae434a4bf7e6d3d37df")

if identities.google is not None:
    print("Google identity found, access token is ", identities.google.access_token)

if identities.github is not None:
    # do your stuff

# This applies to every third-party auth provider supported by PluginLab although each might give or not give some information.

Here is the class used to represent an identity:

@dataclass
class IdentityProviderData:
    provider: str;
    provider_user_id: str;
    access_token_expires_at_ms: int | None;
    refresh_token_expires_at_ms: int | None;
    last_used_at_ms: int | None;
    access_token: str | None;
    refresh_token: str | None;

List members

Basic

paginated_result = auth.get_members()

for member in paginated_result.items:
    print(member.id)

With adjustable limit and pagination

You can request up to 100 members at a time and get a specific page by providing a cursor obtained from a previous call.

paginated_result1 = auth.get_members(50)
cursor = paginated_result1.next_page_cursor

if not cursor is None:
    paginated_result2 = auth.get_members(50, cursor)

Create a member

created_member = auth.create_member(
        email='johndoe@example.com',
        password='12345',
        is_verified=True,
        metadata={
            'origin': 'backend-sdk'
        }
)

print(created_member)

As the typings show, both is_verified and metadata fields are optional to create a user.

Update a member

auth.update_member(
        id='mem_ec9fd884f7fc81fc9e5576d213b6e826d3109d26',
        given_name="John the king of examples",
        family_name="Doe",
        name="John Doe",
        picture_url="https://example.com/john-doe.png",
        metadata={}
)

Except the id field that is used to identify the user to update, all the other updatable fields are optional in this function call.

Delete a member

auth.delete_member(
    id='mem_ec9fd884f7fc81fc9e5576d213b6e826d3109d26',
)

Note that the member ID is derived from the email the user used to sign up. Therefore recreating an account with the same email will NOT reset usage quotas.

Get user quota information

Since version 0.4.0 you can retrieve the current quota usage of a plugin member thanks to the monetization module:

monetization = app.get_monetization();

quota_usage = monetization.get_member_quota_usage(member_id);

if quota_usage.is_over_limit:
    print(f'User exceeded their quota, it will be reset in {quota_usage.reset_in_days} days.')

Dealing with webhooks

Pluginlab signs each webhook payload it sends you using a secret key you can retrieve from your webhooks settings on the Pluginlab dashboard.

This package provides facilities to easiliy verifiy the payload of a webhook.

Here is how, using a flask handler as an example:

import os
from pluginlab_admin import WebhookHeaders, Webhook

webhook_secret = os.getenv('WEBHOOK_SECRET')
webhook = Webhook(webhook_secret)

@app.route('/webhook', methods=['POST'])
def api():
    sig = request.headers.get(WebhookHeaders.Signature.value)
    raw_body = request.get_data(as_text=True)

    if not sig:
        return jsonify({'message': 'No signature was found.'})

    if not webhook.is_signature_valid(raw_body, sig):
        return jsonify({'message': 'Invalid signature.'})

    // process the payload as you like

Make sure you are providing the is_signature_valid method with the raw body of the request, as it was originally sent.

Events

On PluginLab, an event is used as a representaiton of a plugin request and is traditionally generated on each request made by ChatGPT. The SDK offers limited but useful utilities to deal with events.

To get started, you need to leverage the event service by calling the app.get_event method.

// assuming app was previously initialized as showed above
event = app.get_event();

Create a custom event

If you want to create custom events that will appear in your PluginLab dashboard and count as part of your users' quota, you can rely on the create_custom method.

This is especially useful if your service is accessible from other means that ChatGPT but you still want to account for usage using PluginLab.

from pluginlab_admin import EventLocation

location = EventLocation(
    country_code="US",
    subdivision_code="CA", # optional
)

event.create_custom(
    # case insensitive, max. 10 chars
    event_source="WEB_UI",
    # optional, quota ignored if not present
    member_id="mem_fd9a1ba5e385e3d97412cdfbd7b8284c4f0c8e18",
    # optional
    location=location,
    # optional, defaults to true
    is_in_quota=True
)

Assuming the provided member_id refers to a valid plugin member then a new event will get created once the above code runs. It will appear in your PluginLab dashboard's event section.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pluginlab_admin-0.4.1.tar.gz (10.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pluginlab_admin-0.4.1-py3-none-any.whl (10.0 kB view details)

Uploaded Python 3

File details

Details for the file pluginlab_admin-0.4.1.tar.gz.

File metadata

  • Download URL: pluginlab_admin-0.4.1.tar.gz
  • Upload date:
  • Size: 10.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.11.5 Darwin/22.5.0

File hashes

Hashes for pluginlab_admin-0.4.1.tar.gz
Algorithm Hash digest
SHA256 5e0715b64190f25f32dfd775dc44588635873982c79ec1440012beb3707f98fe
MD5 8ba8b162c2c3a89c087f8706be1701a3
BLAKE2b-256 161170ab408fca0dd650125c62f18ea08f435247e589b67c8b80bab1ff9f3a47

See more details on using hashes here.

File details

Details for the file pluginlab_admin-0.4.1-py3-none-any.whl.

File metadata

  • Download URL: pluginlab_admin-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 10.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.11.5 Darwin/22.5.0

File hashes

Hashes for pluginlab_admin-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 def3fdf1b0ff76d0ec1733626695ecf138833dc151f26fb78a3479ea29ac8655
MD5 6d2f71359f08dc8169381e6264d78aee
BLAKE2b-256 6e9f4468cae0b75372d36b9ae53e4a818e728c67295f55d2db500a702169e694

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page