This is a simple library for working with the gmfy api.
Project description
Our project is Python library that allows easy integration with gmfy API. With this SDK, you can conveniently manage mechanics that allow you to adjust user behavior, but also measure the effectiveness of such correction.
How it works 🎮
GMFY receives events related to user actions in the gamified system. This allows you to analyze user behavior before and after the introduction of gamification.
Through the administrative interface, various game mechanics are configured, taking into account incoming events. This is how ratings and leaderboards are built, user achievements are calculated and corporate currencies are awarded.
In order to give users feedback, you need to visualize your achievements. This could be a block in an existing user profile, contextual widgets, or a separate page with achievement results, available to users authorized in the gamified system.
Installation Guide ⤵️
To install the library, you need to choose how you want to use it: synchronously, asynchronously, or both. This approach ensures that you only install the necessary dependencies, keeping your project clean and efficient. Depending on your use case, you can select the appropriate mode as follows:
- Use synchronously:
pip install 'gmfy[sync]'
- Use asynchronously:
pip install 'gmfy[async]'
- Use both synchronously and asynchronously:
pip install 'gmfy[sync,async]'
By selecting the appropriate mode, you ensure that your project includes only the dependencies it needs, avoiding unnecessary clutter.
Quick Start ⭐
The first thing you need to do is initialize the SDK to interact with GMFY
Import a synchronous or asynchronous class to initialize your data. As an example, we will consider both options
from gmfy.sync_clients.gmfy_client import GMFYClientSync
from gmfy.async_clients.gmfy_client import GMFYClientAsync
### Synchronous use ###
gmfy_sync = GMFYClientSync(GMFY_API_KEY, GMFY_URL)
### Asynchronous use ###
gmfy_async = GMFYClientAsync(GMFY_API_KEY, GMFY_URL)
❗Replace GMFY_API_KEY and GMFY_URL with your actual credentials.❗
If you want to change such parameters as request verification or request timeout, you can specify these parameters additionally:
from gmfy.sync_clients.gmfy_client import GMFYClientSync
from gmfy.async_clients.gmfy_client import GMFYClientAsync
### Synchronous use ###
gmfy_sync = GMFYClientSync(GMFY_API_KEY, GMFY_URL, verify=True, timeout=120)
### Asynchronous use ###
gmfy_async = GMFYClientAsync(GMFY_API_KEY, GMFY_URL, verify=True, timeout=120)
POST methods ➡️
1️⃣ Create events to GMFY
1. Define Event Types and Actions
Create custom classes inheriting from BaseEventType and BaseEventAction. For example:
from gmfy import BaseEventAction, BaseEventType
class EventType(BaseEventType):
subscription = "subscription"
register = "register"
visit_user = "visit_user"
class EventAction(BaseEventAction):
create = "create"
remove = "remove"
- EventType must inherit from BaseEventType
- EventAction must inherit from BaseEventAction
You can also expand these classes with your own functionality, for example likes or dislikes.
This needs to be done so that you can add your types and actions.
❕You can use both the list of events and single events. To begin with, we will analyze the use of sending several events ❕
2. Create your events
Now you need to create your own events. They can be classically, actionable, or have an idempotency key. Depending on what type of event you need, inherit from a specific class:
- Classic Event
It can be an ordinary event, for example, user registration on the site:
from gmfy import BaseEvent
from typing import Literal
from pydantic import Field
class RegisterEvent(BaseEvent):
event_type: Literal[EventType.register] = Field(exclude=True)
- Action Event
This event is needed for actions that can be created and removed. For example, likes, subscriptions, and so on:
from gmfy import BaseActionEvent
from typing import Literal
from pydantic import Field
class SubscriptionEvent(BaseActionEvent):
event_type: Literal[EventType.subscription] = Field(exclude=True)
- Unique Event
This event is needed to identify the action. For example, viewing specific content:
from gmfy import BaseUniqueEvent
from typing import Literal
from pydantic import Field
class VisitUserEvent(BaseUniqueEvent):
event_type: Literal[EventType.visit_user] = Field(exclude=True)
❗ Important: If you skip this step, you will get a TypeError error:
TypeError: Event classes inherited from BaseEvent were not found in your project. Ensure you've created your events by inheriting from BaseEvents.
To resolve this issue, ensure that your events are properly set up by inheriting from BaseEvents
.
Create a Python package and include a file where you initialize your classes that extend BaseEvents
.
This step is essential for smooth operation.
3. Prepare data for send events
To send data, you can use class EventData to work with objects:
from gmfy.data import EventData
create_subscription_event = EventData(
event_type=EventType.subscription,
user_id=f"{user_id}",
event_action=EventAction.create
).model_dump(by_alias=True)
register_event = EventData(
event_type=EventType.register,
user_id=f"{user_id}",
).model_dump(by_alias=True)
visit_user_event = EventData(
event_type=EventType.visit_user,
user_id=f"{user_id}",
idempotence_key=f"{instance.id}",
).model_dump(by_alias=True)
event_data = [create_subscription_event, register_event, visit_user_event]
Or you can use a dictionary structure to provide the data to be sent
event_data = [
{
"event_type": EventType.subscription,
"user_id": f"{user.id}",
"event_action": EventAction.create,
},
{
"event_type": EventType.register,
"user_id": f"{user.id}",
},
{
"event_type": EventType.visit_user,
"user_id": f"{user.id}",
"idempotence_key": f"{instance.id}",
},
]
4. Send events
Now that you have prepared the data for sending, you can send a request to GMFY and create an event.
To do this, call the create_batch_events method regardless of what type of synchronization you have chosen
### Synchronous use ###
gmfy_sync.create_batch_events(event_data)
### Asynchronous use ###
await gmfy_async.create_batch_events(event_data)
Well, now let's figure out how you can send not just a list of events, but single events
The basic logic for preparing the data and sending the request does not change. The only important thing is that now you need to work with dict instead of list. Let's see the differences from these options:
1. Prepare data for send single event
from gmfy import EventData
event_data = EventData(
event_type=EventType.subscription,
user_id=f"{user_id}",
event_action=EventAction.create
).model_dump(by_alias=True)
Well, according to tradition, if you want to work directly with dictionaries, then do this:
event_data = {
"event_type": EventType.subscription,
"user_id": f"{user.id}",
"event_action": EventAction.create,
},
2. Create your event
from gmfy import BaseActionEvent
from typing import Literal
from pydantic import Field
class SubscriptionEvent(BaseActionEvent):
event_type: Literal[EventType.subscription] = Field(exclude=True)
3. Send single event
Now we can send a request to create one event. To do this, use the create_event method as follows:
### Synchronous use ###
gmfy_sync.create_event(event_data)
### Asynchronous use ###
await gmfy_async.create_event(event_data)
2️⃣ Create payments to GMFY
To send a post request to send a payment to GMFY, follow these steps:
1. Prepare data for send payment
Similar to the previous example, you can use a class or create your own data dictionary. Both options are presented below:
- Using the class PaymentData:
from gmfy import PaymentData, LocaleEnum
payment_data = PaymentData(
amount={"value": 100, "currency": "USD"},
confirmation={"returnUrl": "https://example.com/"},
user_id=f"{user_id}",
description="Payment for order #123",
locale=LocaleEnum.EN,
).model_dump(by_alias=True)
- Using dictionary:
from gmfy import LocaleEnum
payment_data = {
"amount": {"value": 100, "currency": "USD"},
"confirmation": {"returnUrl": "https://example.com/"},
"user_id": f"{user_id}",
"description": "Payment for order #123",
"locale": LocaleEnum.EN,
}
2. Use basic ones or create your own classes for data management
To validate data, you can use the base classes BasePayment, BaseAmount and BaseConfirmation or override them if you have such a need:
- Use base classes:
from gmfy import BasePayment
payment = BasePayment(**payment_data)
- Create your own classes:
from pydantic import Field
from gmfy import BasePayment, BaseAmount, BaseConfirmation
class CustomAmount(BaseAmount): ...
# modify the class according to your needs
class CustomConfirmation(BaseConfirmation): ...
# modify the class according to your needs
class CustomPayment(BasePayment):
amount: CustomAmount = Field(...)
confirmation: CustomConfirmation = Field(...)
# modify the class according to your needs
3. Use the create_payment method to send a request to GMFY:
- If you used a base class:
### Synchronous use ###
gmfy_sync.create_payment(BasePayment(**payment_data))
### Asynchronous use ###
await gmfy_async.create_payment(BasePayment(**payment_data))
- If you created your own class:
### Synchronous use ###
gmfy_sync.create_payment(CustomPayment(**payment_data))
### Asynchronous use ###
await gmfy_async.create_payment(CustomPayment(**payment_data))
_Unlike creating an event, when creating a payment you will receive a response statusof 200, not 201, as
well as a response from the server:_
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"clientId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "CREATED",
"confirmationUrl": "string"
}
3️⃣ Create resend code to GMFY
You can also create a resend code by passing the payment id like this:
### Synchronous use ###
gmfy_sync.create_resend_code(payment_id=f"{payment_id}")
### Asynchronous use ###
await gmfy_async.create_resend_code(payment_id=f"{payment_id}")
It is important to note that you will receive a 200 OK status in response, as well as the following response:
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"clientId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"value": 0,
"returnUrl": "string",
"description": "string",
"currency": "string",
"status": "CREATED",
"locale": "RU",
"expiresIn": 0
}
GET methods ⬅️
1️⃣ Get user's data from GMFY
You can get information about all users or information about one user by ID using the get_users method
- Get a list of all users information:
### Synchronous use ###
gmfy_sync.get_users()
### Asynchronous use ###
await gmfy_async.get_users()
- Get information about one user by id
### Synchronous use ###
gmfy_sync.get_users(user_id=f"{user_id}")
### Asynchronous use ###
await gmfy_async.get_users(user_id=f"{user_id}")
*️⃣ Example response:
[
{
"userId": "string",
"clientId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"userRatings": [
{
"userId": "string",
"clientId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"ratingId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "string",
"value": 0,
"metaInfo": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
},
"position": 0
}
],
"userChallenges": [
{
"userId": "string",
"challengeId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"clientId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"progress": 0,
"passedSteps": [
{
"challengeStepId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"order": 0,
"weight": 0,
"dateComplete": "2024-08-19T13:03:31.653Z"
}
],
"metaInfo": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
},
"name": "string"
}
],
"userBadges": [
{
"userId": "string",
"badgeId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"clientId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"acquisitionDate": "2024-08-19T13:03:31.653Z",
"metaInfo": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
},
"name": "string",
"description": "string",
"permanent": true,
"count": 0
}
],
"userFeatures": [
{
"userId": "string",
"featureId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"clientId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"accessDate": "2024-08-19T13:03:31.653Z",
"metaInfo": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
},
"name": "string",
"description": "string"
}
],
"userAccountBalances": [
{
"userId": "string",
"clientId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"resourceKey": "string",
"amount": 0
}
]
}
]
2️⃣ Get user badges by user id
To get a list of user badges, use the get_user_badges method, passing it the user id:
### Synchronous use ###
gmfy_sync.get_user_badges(user_id=f"{user_id}")
### Asynchronous use ###
await gmfy_async.get_user_badges(user_id=f"{user_id}")
*️⃣ Example response:
[
{
"userId": "string",
"badgeId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"clientId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"acquisitionDate": "2024-08-19T14:34:11.608Z",
"metaInfo": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
},
"name": "string",
"description": "string",
"permanent": true,
"count": 0
}
]
3️⃣ Get top of users in rating
Also you can get top of users in rating by id:
### Synchronous use ###
gmfy_sync.get_rating_top_users(rating_id=f"{rating_id})
### Asynchronous use ###
await gmfy_async.get_rating_top_users(rating_id=f"{rating_id}")
❗By default request has parameters offset = 0, limit = 10, sorted by ASC. But if you want to override them, you can do it like this:
### Synchronous use ###
gmfy_sync.get_rating_top_users(
rating_id=f"{rating_id}",
offset=5,
limit=20,
sort="DESC"
)
### Asynchronous use ###
gmfy_async.get_rating_top_users(
rating_id=f"{rating_id}",
offset=5,
limit=20,
sort="DESC"
)
*️⃣ Example response:
[
{
"userId": "string",
"clientId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"ratingId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "string",
"value": 0,
"metaInfo": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
},
"position": 0
}
]
4️⃣ Get top of users in challenge
You can get top of users in challenge by id:
### Synchronous use ###
gmfy_sync.get_challenge_top_users(challenge_id=f"{challenge_id}")
### Asynchronous use ###
await gmfy_async.get_challenge_top_users(challenge_id=f"{challenge_id}")
❗By default request has parameter limit = 10. But if you want to override them, you can do it like this:
### Synchronous use ###
gmfy_sync.get_challenge_top_users(challenge_id=f"{challenge_id}", limit=20)
### Asynchronous use ###
await gmfy_async.get_challenge_top_users(challenge_id=f"{challenge_id}", limit=20)
*️⃣ Example response:
[
{
"userId": "string",
"challengeId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"clientId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"progress": 0,
"passedSteps": [
{
"challengeStepId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"order": 0,
"weight": 0,
"dateComplete": "2024-08-19T14:20:26.219Z"
}
],
"metaInfo": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
},
"name": "string"
}
]
5️⃣ Get information about payment by id
Using the get_payment method you can get payment information like this
### Synchronous use ###
gmfy_sync.get_payment(payment_id=f"{payment_id}")
### Asynchronous use ###
await gmfy_async.get_payment(payment_id=f"{payment_id}")
- *️⃣ Example response:
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"clientId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"value": 0,
"returnUrl": "string",
"description": "string",
"currency": "string",
"status": "CREATED",
"locale": "RU",
"expiresIn": 0
}
6️⃣ Get notification's information
You can receive notifications using the get_notifications method like this:
### Synchronous use ###
gmfy_sync.get_notifications()
### Asynchronous use ###
await gmfy_async.get_notifications()
- *️⃣ Example response:
[
{
"userId": "string",
"clientId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"message": "string"
}
]
7️⃣ Get unread notification's information:
You can also get information about unread notifications of all users, or for a single user, if you specify his id. This can be done using the get_unread_notifications() method:
- Get unread notifications for all users:
### Synchronous use ###
gmfy_sync.get_unread_notifications()
### Asynchronous use ###
await gmfy_async.get_unread_notifications()
- Get unread notifications for single user by id:
### Synchronous use ###
gmfy_sync.get_unread_notifications(user_id=f"{user_id}")
### Asynchronous use ###
await gmfy_async.get_unread_notifications(user_id=f"{user_id}")
- *️⃣ Example response for both options:
[
{
"userId": "string",
"clientId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"message": "string"
}
]
8️⃣ Get version of API GMFY
And, of course, you can get the API version using previously initialized classes using the get_api_version method
### Synchronous use ###
gmfy_sync.get_api_version()
### Asynchronous use ###
await gmfy_async.get_api_version()
*️⃣ Example response:
{
"version": "1.0",
"deploymentDate": "2024-07-22T17:28:03.876Z"
}
Contributors and Contact 💬
The GMFY SDK library were developed by Evgeny Izvekov and Yuriy Belotserkovskiy, and is actively maintained by our team. If you have any questions, suggestions, or feedback, feel free to reach out to us.
Happy gamifying! 👾
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file gmfy-0.0.4.tar.gz
.
File metadata
- Download URL: gmfy-0.0.4.tar.gz
- Upload date:
- Size: 17.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.12.5 Linux/6.8.0-40-generic
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | e2478ac3499154be46ddf03425250c68cd0094f08d14251eef61829df9406a1a |
|
MD5 | 472fc739f583ab3bdef213473042f63f |
|
BLAKE2b-256 | a2337315822d421b26439b02ae4e28a3206f03bd37b97adb2d7f2249a9a68166 |
File details
Details for the file gmfy-0.0.4-py3-none-any.whl
.
File metadata
- Download URL: gmfy-0.0.4-py3-none-any.whl
- Upload date:
- Size: 16.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.12.5 Linux/6.8.0-40-generic
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | a49a66d7ce91164d746e79770e8c44f81dce3edb5e50ea4fe850e073f12b0d9e |
|
MD5 | ecc206f652c1820071bf10dce4b7d21e |
|
BLAKE2b-256 | 3cc055445430428f309dc0562936a7494614ff9331754373185a3fa46ffa511b |