gmfy


Namegmfy JSON
Version 0.0.3 PyPI version JSON
download
home_pageNone
SummaryThis is a simple library for working with the gmfy api.
upload_time2024-08-28 13:23:38
maintainerNone
docs_urlNone
authorEvgeny Izvekov
requires_python<4.0,>=3.12
licenseNone
keywords gmfy api gamification
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <a href="https://github.com/astral-sh/ruff"><img alt="ruff" src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json"></a>
<a href="https://pypi.org/project/gmfy/"><img alt="pypi version" src="https://img.shields.io/pypi/v/gmfy"></a>
<a href="https://gmfycode.gitlab.yandexcloud.net/gmfy-sdk/gmfy-sdk-python/activity"><img alt="Number of tests" src="https://img.shields.io/badge/tests-42 passed-emerald"></a>

<br>
<div align="center">
  <a href="https://gmfy.io/">
    <img alt="GMFY" width="400" src="https://static.tildacdn.com/tild6136-3638-4632-b632-383132653436/logo.svg">
  </a>
</div>
<br>

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:

```bash
pip install 'gmfy[sync]'
```

- Use asynchronously:

```bash
pip install 'gmfy[async]'
```

- Use both synchronously and asynchronously:

```bash
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

```python
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:

```python
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:

```python
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:
```python
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:
```python
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:
```python
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**:

```text
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:

```python
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

```python
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

```python
### 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*

```python
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:

```python
event_data = {
    "event_type": EventType.subscription,
    "user_id": f"{user.id}",
    "event_action": EventAction.create,
},
```
### 2. *Create your event*
```python
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:

```python
### 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:

```python
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:

```python
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:

```python
from gmfy import BasePayment

payment = BasePayment(**payment_data)
```

- Create your own classes:

```python
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:

```python
### 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:

```python
### 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:_

```json
{
  "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:

```python
### 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:

```json
{
  "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

1) _Get a list of all users information:_

```python
### Synchronous use ###
gmfy_sync.get_users()

### Asynchronous use ###
await gmfy_async.get_users()
```

2) _Get information about one user by id_

```python
### 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:_

```json
[
  {
    "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:

```python
### 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:_

```json
[
  {
    "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:

```python
### 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:_

```python
### 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:_

```json
[
  {
    "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:

```python
### 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:_

```python
### 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:_

```json
[
  {
    "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

```python
### 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:_

```json
{
  "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:

```python
### Synchronous use ###
gmfy_sync.get_notifications()

### Asynchronous use ###
await gmfy_async.get_notifications()
```

- *️⃣ _Example response:_

```json
[
  {
    "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:
```python
### Synchronous use ###
gmfy_sync.get_unread_notifications()

### Asynchronous use ###
await gmfy_async.get_unread_notifications()
```

- Get unread notifications for single user by id:
```python
### 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:_

```json
[
  {
    "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

```python
### Synchronous use ###
gmfy_sync.get_api_version()

### Asynchronous use ###
await gmfy_async.get_api_version()
```

*️⃣ _Example response:_

```json
{
  "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.

- **Evgeny Izvekov**
    - <a href=https://gitlab.rdclr.ru/evgeny.izvekov>*GitLab*</a>
    - <a href=mailto:evgeny.izvekov@redcollar.ru>*Email*</a>


- **Yuriy Belotserkovskiy**
    - <a href=https://gitlab.rdclr.ru/yuriy.belotserkovskiy>*GitLab*</a>
    - <a href=mailto:yuriy.belotserkovskiy@redcollar.ru>*Email*</a>

### **Happy gamifying! 👾**

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "gmfy",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.12",
    "maintainer_email": null,
    "keywords": "gmfy API gamification",
    "author": "Evgeny Izvekov",
    "author_email": "evgeny.izvekov@redcollar.ru",
    "download_url": "https://files.pythonhosted.org/packages/38/86/8591beb1046a4182e0f6cf08bcafbc2e7359ff8637f372af107132e48c3f/gmfy-0.0.3.tar.gz",
    "platform": null,
    "description": "<a href=\"https://github.com/astral-sh/ruff\"><img alt=\"ruff\" src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\"></a>\n<a href=\"https://pypi.org/project/gmfy/\"><img alt=\"pypi version\" src=\"https://img.shields.io/pypi/v/gmfy\"></a>\n<a href=\"https://gmfycode.gitlab.yandexcloud.net/gmfy-sdk/gmfy-sdk-python/activity\"><img alt=\"Number of tests\" src=\"https://img.shields.io/badge/tests-42 passed-emerald\"></a>\n\n<br>\n<div align=\"center\">\n  <a href=\"https://gmfy.io/\">\n    <img alt=\"GMFY\" width=\"400\" src=\"https://static.tildacdn.com/tild6136-3638-4632-b632-383132653436/logo.svg\">\n  </a>\n</div>\n<br>\n\nOur project is Python library that allows easy integration with\ngmfy API. With this SDK, you can conveniently manage mechanics\nthat allow you to adjust user behavior, but also measure the\neffectiveness of such correction.\n\n## How it works \ud83c\udfae\n\nGMFY receives events related to user actions in the gamified\nsystem. This allows you to analyze user behavior before and\nafter the introduction of gamification.\n\nThrough the administrative interface, various game mechanics\nare configured, taking into account incoming events. This is\nhow ratings and leaderboards are built, user achievements are\ncalculated and corporate currencies are awarded.\n\nIn order to give users feedback, you need to visualize your\nachievements. This could be a block in an existing user\nprofile, contextual widgets, or a separate page with\nachievement results, available to users authorized in the\ngamified system.\n\n# **Installation Guide \u2935\ufe0f**\n\nTo install the library, you need to choose how you want to use it: **synchronously**, **asynchronously**, or **both**.\nThis approach ensures that you only install the necessary dependencies, keeping your project clean and efficient.\nDepending on your use case, you can select the appropriate mode as follows:\n\n- Use synchronously:\n\n```bash\npip install 'gmfy[sync]'\n```\n\n- Use asynchronously:\n\n```bash\npip install 'gmfy[async]'\n```\n\n- Use both synchronously and asynchronously:\n\n```bash\npip install 'gmfy[sync,async]'\n```\n\nBy selecting the appropriate mode, you ensure that your project includes only\nthe dependencies it needs, avoiding unnecessary clutter.\n\n# **Quick Start \u2b50**\n\n#### _The first thing you need to do is *initialize the SDK* to interact with GMFY_\n\nImport a synchronous or asynchronous class to initialize your data. As an example, we will consider both options\n\n```python\nfrom gmfy.sync_clients.gmfy_client import GMFYClientSync\nfrom gmfy.async_clients.gmfy_client import GMFYClientAsync\n\n### Synchronous use ###\ngmfy_sync = GMFYClientSync(GMFY_API_KEY, GMFY_URL)\n\n### Asynchronous use ###\ngmfy_async = GMFYClientAsync(GMFY_API_KEY, GMFY_URL)\n```\n\n#### __\u2757Replace GMFY_API_KEY and GMFY_URL with your actual credentials.\u2757__\n\nIf you want to change such parameters as request verification or request timeout, you can specify these parameters additionally:\n\n```python\nfrom gmfy.sync_clients.gmfy_client import GMFYClientSync\nfrom gmfy.async_clients.gmfy_client import GMFYClientAsync\n\n\n### Synchronous use ###\ngmfy_sync = GMFYClientSync(GMFY_API_KEY, GMFY_URL, verify=True, timeout=120)\n\n### Asynchronous use ###\ngmfy_async = GMFYClientAsync(GMFY_API_KEY, GMFY_URL, verify=True, timeout=120)\n```\n# __POST methods \u27a1\ufe0f__\n\n## 1\ufe0f\u20e3 *_Create events to GMFY_*\n\n### 1. *Define Event Types and Actions*\n\nCreate custom classes inheriting from **BaseEventType** and **BaseEventAction**. For example:\n\n```python\nfrom gmfy import BaseEventAction, BaseEventType\n\n\nclass EventType(BaseEventType):\n    subscription = \"subscription\"\n    register = \"register\"\n    visit_user = \"visit_user\"\n\n\nclass EventAction(BaseEventAction):\n    create = \"create\"\n    remove = \"remove\"\n```\n\n- _**EventType** must inherit from **BaseEventType**_\n- _**EventAction** must inherit from **BaseEventAction**_\n\nYou can also expand these classes with your own functionality,\nfor example likes or dislikes.\n\nThis needs to be done so that you can add your types and actions.\n\n\u2755You can use both the list of events and single events. To begin with, we will analyze the use of sending several events \u2755\n\n### 2. *Create your events*\n\nNow you need to create your own events. They can be classically, actionable, or have an idempotency key.\nDepending on what type of event you need, inherit from a specific class:\n\n- _Classic Event_\n\nIt can be an ordinary event, for example, user registration on the site:\n```python\nfrom gmfy import BaseEvent\nfrom typing import Literal\nfrom pydantic import Field\n\n\nclass RegisterEvent(BaseEvent):\n    event_type: Literal[EventType.register] = Field(exclude=True)\n```\n\n- _Action Event_\n\nThis event is needed for actions that can be created and removed. For example, likes, subscriptions, and so on:\n```python\nfrom gmfy import BaseActionEvent\nfrom typing import Literal\nfrom pydantic import Field\n\n\nclass SubscriptionEvent(BaseActionEvent):\n    event_type: Literal[EventType.subscription] = Field(exclude=True)\n```\n\n- _Unique Event_\n\nThis event is needed to identify the action. For example, viewing specific content:\n```python\nfrom gmfy import BaseUniqueEvent\nfrom typing import Literal\nfrom pydantic import Field\n\n\nclass VisitUserEvent(BaseUniqueEvent):\n    event_type: Literal[EventType.visit_user] = Field(exclude=True)\n```\n\n#### \u2757 **Important: If you skip this step, you will get a TypeError error**:\n\n```text\nTypeError: Event classes inherited from BaseEvent were not found in your project. Ensure you've created your events by inheriting from BaseEvents.\n```\nTo resolve this issue, ensure that your events are properly set up by inheriting from `BaseEvents`.\nCreate a Python package and include a file where you initialize your classes that extend `BaseEvents`.\nThis step is essential for smooth operation.\n\n### 3. *Prepare data for send events*\n\nTo send data, you can use class **EventData** to work with objects:\n\n```python\nfrom gmfy.data import EventData\n\ncreate_subscription_event = EventData(\n        event_type=EventType.subscription,\n        user_id=f\"{user_id}\",\n        event_action=EventAction.create\n    ).model_dump(by_alias=True)\n\nregister_event = EventData(\n        event_type=EventType.register,\n        user_id=f\"{user_id}\",\n    ).model_dump(by_alias=True)\n\nvisit_user_event = EventData(\n        event_type=EventType.visit_user,\n        user_id=f\"{user_id}\",\n        idempotence_key=f\"{instance.id}\",\n    ).model_dump(by_alias=True)\n\nevent_data = [create_subscription_event, register_event, visit_user_event]\n```\n\nOr you can use a dictionary structure to provide the data to be sent\n\n```python\nevent_data = [\n    {\n        \"event_type\": EventType.subscription,\n        \"user_id\": f\"{user.id}\",\n        \"event_action\": EventAction.create,\n    },\n    {\n        \"event_type\": EventType.register,\n        \"user_id\": f\"{user.id}\",\n    },\n    {\n        \"event_type\": EventType.visit_user,\n        \"user_id\": f\"{user.id}\",\n        \"idempotence_key\": f\"{instance.id}\",\n    },\n]\n```\n\n### 4. *Send events*\n\nNow that you have prepared the data for sending, you can send a request to GMFY and create an event.\n\nTo do this, call the **create_batch_events** method regardless of what type of synchronization you have chosen\n\n```python\n### Synchronous use ###\ngmfy_sync.create_batch_events(event_data)\n\n### Asynchronous use ###\nawait gmfy_async.create_batch_events(event_data)\n```\n\n### Well, now let's figure out how you can send not just a list of events, but single events\n\nThe basic logic for preparing the data and sending the request does not change.\nThe only important thing is that now you need to work with dict instead of list.\nLet's see the differences from these options:\n\n### 1. *Prepare data for send single event*\n\n```python\nfrom gmfy import EventData\n\nevent_data = EventData(\n    event_type=EventType.subscription,\n    user_id=f\"{user_id}\",\n    event_action=EventAction.create\n).model_dump(by_alias=True)\n```\n\nWell, according to tradition, if you want to work directly with dictionaries, then do this:\n\n```python\nevent_data = {\n    \"event_type\": EventType.subscription,\n    \"user_id\": f\"{user.id}\",\n    \"event_action\": EventAction.create,\n},\n```\n### 2. *Create your event*\n```python\nfrom gmfy import BaseActionEvent\nfrom typing import Literal\nfrom pydantic import Field\n\n\nclass SubscriptionEvent(BaseActionEvent):\n    event_type: Literal[EventType.subscription] = Field(exclude=True)\n```\n\n### 3. *Send single event*\n\nNow we can send a request to create one event. To do this, use the **create_event** method as follows:\n\n```python\n### Synchronous use ###\ngmfy_sync.create_event(event_data)\n\n### Asynchronous use ###\nawait gmfy_async.create_event(event_data)\n```\n\n## 2\ufe0f\u20e3 *_Create payments to GMFY_*\n\nTo send a post request to send a payment to GMFY, follow these steps:\n\n### 1. Prepare data for send payment\n\nSimilar to the previous example, you can use a class or create your own data dictionary.\nBoth options are presented below:\n\n- Using the class PaymentData:\n\n```python\nfrom gmfy import PaymentData, LocaleEnum\n\npayment_data = PaymentData(\n    amount={\"value\": 100, \"currency\": \"USD\"},\n    confirmation={\"returnUrl\": \"https://example.com/\"},\n    user_id=f\"{user_id}\",\n    description=\"Payment for order #123\",\n    locale=LocaleEnum.EN,\n).model_dump(by_alias=True)\n```\n\n- Using dictionary:\n\n```python\nfrom gmfy import LocaleEnum\n\npayment_data = {\n    \"amount\": {\"value\": 100, \"currency\": \"USD\"},\n    \"confirmation\": {\"returnUrl\": \"https://example.com/\"},\n    \"user_id\": f\"{user_id}\",\n    \"description\": \"Payment for order #123\",\n    \"locale\": LocaleEnum.EN,\n}\n```\n\n### 2. Use basic ones or create your own classes for data management\n\nTo validate data, you can use the base classes **BasePayment**, **BaseAmount** and\n**BaseConfirmation** or override them if you have such a need:\n\n- Use base classes:\n\n```python\nfrom gmfy import BasePayment\n\npayment = BasePayment(**payment_data)\n```\n\n- Create your own classes:\n\n```python\nfrom pydantic import Field\n\nfrom gmfy import BasePayment, BaseAmount, BaseConfirmation\n\n\nclass CustomAmount(BaseAmount): ...\n# modify the class according to your needs\n\n\nclass CustomConfirmation(BaseConfirmation): ...\n# modify the class according to your needs\n\n\nclass CustomPayment(BasePayment):\n    amount: CustomAmount = Field(...)\n    confirmation: CustomConfirmation = Field(...)\n    # modify the class according to your needs\n```\n\n### 3. Use the **create_payment** method to send a request to GMFY:\n\n- If you used a base class:\n\n```python\n### Synchronous use ###\ngmfy_sync.create_payment(BasePayment(**payment_data))\n\n### Asynchronous use ###\nawait gmfy_async.create_payment(BasePayment(**payment_data))\n```\n\n- If you created your own class:\n\n```python\n### Synchronous use ###\ngmfy_sync.create_payment(CustomPayment(**payment_data))\n\n### Asynchronous use ###\nawait gmfy_async.create_payment(CustomPayment(**payment_data))\n```\n\n#### _Unlike creating an event, when creating a payment you will receive a response statusof **200**, not **201**, as\nwell as a response from the server:_\n\n```json\n{\n  \"id\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n  \"clientId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n  \"status\": \"CREATED\",\n  \"confirmationUrl\": \"string\"\n}\n```\n\n## 3\ufe0f\u20e3 *_Create resend code to GMFY_*\n\nYou can also create a resend code by passing the payment id like this:\n\n```python\n### Synchronous use ###\ngmfy_sync.create_resend_code(payment_id=f\"{payment_id}\")\n\n### Asynchronous use ###\nawait gmfy_async.create_resend_code(payment_id=f\"{payment_id}\")\n```\n\nIt is important to note that you will receive a 200 OK status in response, as well as the following response:\n\n```json\n{\n  \"id\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n  \"clientId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n  \"value\": 0,\n  \"returnUrl\": \"string\",\n  \"description\": \"string\",\n  \"currency\": \"string\",\n  \"status\": \"CREATED\",\n  \"locale\": \"RU\",\n  \"expiresIn\": 0\n}\n```\n\n# __GET methods \u2b05\ufe0f__\n\n## *_1\ufe0f\u20e3 Get user's data from GMFY_*\n\nYou can get information about all users or information about one user by ID using the **get_users** method\n\n1) _Get a list of all users information:_\n\n```python\n### Synchronous use ###\ngmfy_sync.get_users()\n\n### Asynchronous use ###\nawait gmfy_async.get_users()\n```\n\n2) _Get information about one user by id_\n\n```python\n### Synchronous use ###\ngmfy_sync.get_users(user_id=f\"{user_id}\")\n\n### Asynchronous use ###\nawait gmfy_async.get_users(user_id=f\"{user_id}\")\n```\n\n*\ufe0f\u20e3 _Example response:_\n\n```json\n[\n  {\n    \"userId\": \"string\",\n    \"clientId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    \"userRatings\": [\n      {\n        \"userId\": \"string\",\n        \"clientId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n        \"ratingId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n        \"name\": \"string\",\n        \"value\": 0,\n        \"metaInfo\": {\n          \"additionalProp1\": \"string\",\n          \"additionalProp2\": \"string\",\n          \"additionalProp3\": \"string\"\n        },\n        \"position\": 0\n      }\n    ],\n    \"userChallenges\": [\n      {\n        \"userId\": \"string\",\n        \"challengeId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n        \"clientId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n        \"progress\": 0,\n        \"passedSteps\": [\n          {\n            \"challengeStepId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n            \"order\": 0,\n            \"weight\": 0,\n            \"dateComplete\": \"2024-08-19T13:03:31.653Z\"\n          }\n        ],\n        \"metaInfo\": {\n          \"additionalProp1\": \"string\",\n          \"additionalProp2\": \"string\",\n          \"additionalProp3\": \"string\"\n        },\n        \"name\": \"string\"\n      }\n    ],\n    \"userBadges\": [\n      {\n        \"userId\": \"string\",\n        \"badgeId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n        \"clientId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n        \"acquisitionDate\": \"2024-08-19T13:03:31.653Z\",\n        \"metaInfo\": {\n          \"additionalProp1\": \"string\",\n          \"additionalProp2\": \"string\",\n          \"additionalProp3\": \"string\"\n        },\n        \"name\": \"string\",\n        \"description\": \"string\",\n        \"permanent\": true,\n        \"count\": 0\n      }\n    ],\n    \"userFeatures\": [\n      {\n        \"userId\": \"string\",\n        \"featureId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n        \"clientId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n        \"accessDate\": \"2024-08-19T13:03:31.653Z\",\n        \"metaInfo\": {\n          \"additionalProp1\": \"string\",\n          \"additionalProp2\": \"string\",\n          \"additionalProp3\": \"string\"\n        },\n        \"name\": \"string\",\n        \"description\": \"string\"\n      }\n    ],\n    \"userAccountBalances\": [\n      {\n        \"userId\": \"string\",\n        \"clientId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n        \"resourceKey\": \"string\",\n        \"amount\": 0\n      }\n    ]\n  }\n]\n```\n\n## *_2\ufe0f\u20e3 Get user badges by user id_*\n\nTo get a list of user badges, use the **get_user_badges** method, passing it the user id:\n\n```python\n### Synchronous use ###\ngmfy_sync.get_user_badges(user_id=f\"{user_id}\")\n\n### Asynchronous use ###\nawait gmfy_async.get_user_badges(user_id=f\"{user_id}\")\n```\n\n*\ufe0f\u20e3 _Example response:_\n\n```json\n[\n  {\n    \"userId\": \"string\",\n    \"badgeId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    \"clientId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    \"acquisitionDate\": \"2024-08-19T14:34:11.608Z\",\n    \"metaInfo\": {\n      \"additionalProp1\": \"string\",\n      \"additionalProp2\": \"string\",\n      \"additionalProp3\": \"string\"\n    },\n    \"name\": \"string\",\n    \"description\": \"string\",\n    \"permanent\": true,\n    \"count\": 0\n  }\n]\n```\n\n## *_3\ufe0f\u20e3 Get top of users in rating_*\n\nAlso you can get top of users in rating by id:\n\n```python\n### Synchronous use ###\ngmfy_sync.get_rating_top_users(rating_id=f\"{rating_id})\n\n### Asynchronous use ###\nawait gmfy_async.get_rating_top_users(rating_id=f\"{rating_id}\")\n```\n\n_\u2757By default request has parameters **offset = 0, limit = 10, sorted by ASC**.\nBut if you want to override them, you can do it like this:_\n\n```python\n### Synchronous use ###\ngmfy_sync.get_rating_top_users(\n    rating_id=f\"{rating_id}\",\n    offset=5,\n    limit=20,\n    sort=\"DESC\"\n)\n\n### Asynchronous use ###\ngmfy_async.get_rating_top_users(\n    rating_id=f\"{rating_id}\",\n    offset=5,\n    limit=20,\n    sort=\"DESC\"\n)\n\n```\n\n*\ufe0f\u20e3 _Example response:_\n\n```json\n[\n  {\n    \"userId\": \"string\",\n    \"clientId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    \"ratingId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    \"name\": \"string\",\n    \"value\": 0,\n    \"metaInfo\": {\n      \"additionalProp1\": \"string\",\n      \"additionalProp2\": \"string\",\n      \"additionalProp3\": \"string\"\n    },\n    \"position\": 0\n  }\n]\n```\n\n## *_4\ufe0f\u20e3 Get top of users in challenge_*\n\nYou can get top of users in challenge by id:\n\n```python\n### Synchronous use ###\ngmfy_sync.get_challenge_top_users(challenge_id=f\"{challenge_id}\")\n\n### Asynchronous use ###\nawait gmfy_async.get_challenge_top_users(challenge_id=f\"{challenge_id}\")\n```\n\n_\u2757By default request has parameter **limit = 10**. But if you want to override them, you can do it like this:_\n\n```python\n### Synchronous use ###\ngmfy_sync.get_challenge_top_users(challenge_id=f\"{challenge_id}\", limit=20)\n\n### Asynchronous use ###\nawait gmfy_async.get_challenge_top_users(challenge_id=f\"{challenge_id}\", limit=20)\n```\n\n*\ufe0f\u20e3 _Example response:_\n\n```json\n[\n  {\n    \"userId\": \"string\",\n    \"challengeId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    \"clientId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    \"progress\": 0,\n    \"passedSteps\": [\n      {\n        \"challengeStepId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n        \"order\": 0,\n        \"weight\": 0,\n        \"dateComplete\": \"2024-08-19T14:20:26.219Z\"\n      }\n    ],\n    \"metaInfo\": {\n      \"additionalProp1\": \"string\",\n      \"additionalProp2\": \"string\",\n      \"additionalProp3\": \"string\"\n    },\n    \"name\": \"string\"\n  }\n]\n```\n\n## *_5\ufe0f\u20e3 Get information about payment by id_*\n\nUsing the **get_payment** method you can get payment information like this\n\n```python\n### Synchronous use ###\ngmfy_sync.get_payment(payment_id=f\"{payment_id}\")\n\n### Asynchronous use ###\nawait gmfy_async.get_payment(payment_id=f\"{payment_id}\")\n```\n\n- *\ufe0f\u20e3 _Example response:_\n\n```json\n{\n  \"id\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n  \"clientId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n  \"value\": 0,\n  \"returnUrl\": \"string\",\n  \"description\": \"string\",\n  \"currency\": \"string\",\n  \"status\": \"CREATED\",\n  \"locale\": \"RU\",\n  \"expiresIn\": 0\n}\n```\n\n## *_6\ufe0f\u20e3 Get notification's information_*\n\nYou can receive notifications using the **get_notifications** method like this:\n\n```python\n### Synchronous use ###\ngmfy_sync.get_notifications()\n\n### Asynchronous use ###\nawait gmfy_async.get_notifications()\n```\n\n- *\ufe0f\u20e3 _Example response:_\n\n```json\n[\n  {\n    \"userId\": \"string\",\n    \"clientId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    \"message\": \"string\"\n  }\n]\n```\n\n## *_7\ufe0f\u20e3 Get unread notification's information_*:\nYou can also get information about unread notifications of all users, or for a single user, if you specify his id.\nThis can be done using the **get_unread_notifications()** method:\n\n- Get unread notifications for all users:\n```python\n### Synchronous use ###\ngmfy_sync.get_unread_notifications()\n\n### Asynchronous use ###\nawait gmfy_async.get_unread_notifications()\n```\n\n- Get unread notifications for single user by id:\n```python\n### Synchronous use ###\ngmfy_sync.get_unread_notifications(user_id=f\"{user_id}\")\n\n### Asynchronous use ###\nawait gmfy_async.get_unread_notifications(user_id=f\"{user_id}\")\n```\n\n- *\ufe0f\u20e3 _Example response for both options:_\n\n```json\n[\n  {\n    \"userId\": \"string\",\n    \"clientId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    \"message\": \"string\"\n  }\n]\n```\n\n## *_8\ufe0f\u20e3 Get version of API GMFY_*\n\nAnd, of course, you can get the API version using previously initialized classes using the **get_api_version** method\n\n```python\n### Synchronous use ###\ngmfy_sync.get_api_version()\n\n### Asynchronous use ###\nawait gmfy_async.get_api_version()\n```\n\n*\ufe0f\u20e3 _Example response:_\n\n```json\n{\n  \"version\": \"1.0\",\n  \"deploymentDate\": \"2024-07-22T17:28:03.876Z\"\n}\n```\n\n# **Contributors and Contact \ud83d\udcac**\n\nThe GMFY SDK library were developed by *Evgeny Izvekov* and *Yuriy Belotserkovskiy*,\nand is actively maintained by our team. If you have any\nquestions, suggestions, or feedback, feel free to reach out to us.\n\n- **Evgeny Izvekov**\n    - <a href=https://gitlab.rdclr.ru/evgeny.izvekov>*GitLab*</a>\n    - <a href=mailto:evgeny.izvekov@redcollar.ru>*Email*</a>\n\n\n- **Yuriy Belotserkovskiy**\n    - <a href=https://gitlab.rdclr.ru/yuriy.belotserkovskiy>*GitLab*</a>\n    - <a href=mailto:yuriy.belotserkovskiy@redcollar.ru>*Email*</a>\n\n### **Happy gamifying! \ud83d\udc7e**\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "This is a simple library for working with the gmfy api.",
    "version": "0.0.3",
    "project_urls": {
        "Docs": "https://pypi.org/project/gmfy/"
    },
    "split_keywords": [
        "gmfy",
        "api",
        "gamification"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "bd4617c8770bfc28fd70d110182619501d84dc245d08c69ea96c00c061ed8473",
                "md5": "133476a5c2b33d8129af74c10e52573d",
                "sha256": "e5398600ceb87a77605bccfbe12dfc1e119ac4661c58bbcc0d6244ca4dca568f"
            },
            "downloads": -1,
            "filename": "gmfy-0.0.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "133476a5c2b33d8129af74c10e52573d",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.12",
            "size": 16370,
            "upload_time": "2024-08-28T13:23:36",
            "upload_time_iso_8601": "2024-08-28T13:23:36.706176Z",
            "url": "https://files.pythonhosted.org/packages/bd/46/17c8770bfc28fd70d110182619501d84dc245d08c69ea96c00c061ed8473/gmfy-0.0.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "38868591beb1046a4182e0f6cf08bcafbc2e7359ff8637f372af107132e48c3f",
                "md5": "fb601be14c948059ab5d613955b77f94",
                "sha256": "cdde44b65cde8919a80c2433f9b7eb18e9b7b891ee08902c2974b20bc647a748"
            },
            "downloads": -1,
            "filename": "gmfy-0.0.3.tar.gz",
            "has_sig": false,
            "md5_digest": "fb601be14c948059ab5d613955b77f94",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.12",
            "size": 18032,
            "upload_time": "2024-08-28T13:23:38",
            "upload_time_iso_8601": "2024-08-28T13:23:38.702504Z",
            "url": "https://files.pythonhosted.org/packages/38/86/8591beb1046a4182e0f6cf08bcafbc2e7359ff8637f372af107132e48c3f/gmfy-0.0.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-08-28 13:23:38",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "gmfy"
}
        
Elapsed time: 0.46871s