mirror of
https://github.com/vibe-existing/pyfragment.git
synced 2026-07-25 06:54:31 +00:00
Refactor FragmentAPI to pyfragment
- Renamed the package from `fragmentapi` to `pyfragment` across all modules and tests. - Removed the old wallet utility functions and replaced them with new implementations. - Updated the `pyproject.toml` to reflect the new package name and repository links. - Adjusted all import statements in tests to use the new package name. - Implemented new methods for gifting Telegram Premium, Stars, and topping up TON balance. - Added exception handling for various error scenarios in the API interactions. - Created new utility functions for handling HTTP requests and decoding payloads. - Established a clear structure for types and constants used throughout the library.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
name: Bug report
|
||||
description: Report an issue or unexpected behavior in FragmentAPI.
|
||||
description: Report an issue or unexpected behavior in pyfragment.
|
||||
labels:
|
||||
- bug
|
||||
body:
|
||||
@@ -7,7 +7,7 @@ body:
|
||||
attributes:
|
||||
label: Checklist
|
||||
options:
|
||||
- label: I am sure the error is coming from FragmentAPI code
|
||||
- label: I am sure the error is coming from pyfragment code
|
||||
required: true
|
||||
- label: I have searched the issue tracker for similar bug reports, including closed ones
|
||||
required: true
|
||||
@@ -35,8 +35,8 @@ body:
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: FragmentAPI version
|
||||
description: Run `pip show fragmentapi` inside your virtualenv
|
||||
label: pyfragment version
|
||||
description: Run `pip show pyfragment` inside your virtualenv
|
||||
placeholder: e.g. 2026.1.0
|
||||
validations:
|
||||
required: true
|
||||
@@ -74,7 +74,7 @@ body:
|
||||
description: Provide a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) if applicable.
|
||||
placeholder: |
|
||||
import asyncio
|
||||
from fragmentapi import FragmentClient
|
||||
from pyfragment import FragmentClient
|
||||
|
||||
async def main():
|
||||
client = FragmentClient(...)
|
||||
@@ -91,7 +91,7 @@ body:
|
||||
Traceback (most recent call last):
|
||||
File "main.py", line 7, in main
|
||||
...
|
||||
fragmentapi.types.ParseError: ...
|
||||
pyfragment.types.ParseError: ...
|
||||
render: sh
|
||||
|
||||
- type: textarea
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Ask a question or start a discussion
|
||||
url: https://github.com/bohd4nx/FragmentAPI/discussions
|
||||
url: https://github.com/bohd4nx/pyfragment/discussions
|
||||
about: General questions, ideas, and community help go here — not in the issue tracker.
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
name: Feature request
|
||||
description: Suggest an improvement or new feature for FragmentAPI.
|
||||
description: Suggest an improvement or new feature for pyfragment.
|
||||
labels:
|
||||
- enhancement
|
||||
body:
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: FragmentAPI version
|
||||
label: pyfragment version
|
||||
description: Which version are you running?
|
||||
options:
|
||||
- latest
|
||||
|
||||
@@ -23,7 +23,7 @@ Describe the tests you ran to verify the change and list any relevant details.
|
||||
**Test configuration:**
|
||||
* OS:
|
||||
* Python version:
|
||||
* FragmentAPI version:
|
||||
* pyfragment version:
|
||||
|
||||
## Checklist
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: pypi
|
||||
url: https://pypi.org/project/fragmentapi/
|
||||
url: https://pypi.org/project/pyfragment/
|
||||
permissions:
|
||||
id-token: write
|
||||
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
<b>Python library for the Fragment.com API — gift Telegram Stars, Premium, and top up TON Ads balance.</b>
|
||||
</p>
|
||||
|
||||
[](https://pypi.org/project/fragmentapi/)
|
||||
[](https://pypi.org/project/fragmentapi/)
|
||||
[](https://pypi.org/project/pyfragment/)
|
||||
[](https://pypi.org/project/pyfragment/)
|
||||
[](https://python.org)
|
||||
[](LICENSE)
|
||||
[](https://github.com/bohd4nx/FragmentAPI/stargazers)
|
||||
[](https://github.com/bohd4nx/FragmentAPI/actions)
|
||||
[](LICENSE)
|
||||
[](https://github.com/bohd4nx/pyfragment/stargazers)
|
||||
[](https://github.com/bohd4nx/pyfragment/actions)
|
||||
|
||||
[Report Bug](https://github.com/bohd4nx/FragmentAPI/issues) · [Request Feature](https://github.com/bohd4nx/FragmentAPI/issues) · [**Donate TON**](https://app.tonkeeper.com/transfer/UQCppfw5DxWgdVHf3zkmZS8k1mt9oAUYxQLwq2fz3nhO8No5)
|
||||
[Report Bug](https://github.com/bohd4nx/pyfragment/issues) · [Request Feature](https://github.com/bohd4nx/pyfragment/issues) · [**Donate TON**](https://app.tonkeeper.com/transfer/UQCppfw5DxWgdVHf3zkmZS8k1mt9oAUYxQLwq2fz3nhO8No5)
|
||||
|
||||
</div>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
## 📦 Installation
|
||||
|
||||
```bash
|
||||
pip install fragmentapi
|
||||
pip install pyfragment
|
||||
```
|
||||
|
||||
Requires **Python 3.12+**.
|
||||
@@ -44,7 +44,7 @@ Requires **Python 3.12+**.
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from fragmentapi import FragmentClient
|
||||
from pyfragment import FragmentClient
|
||||
|
||||
client = FragmentClient(
|
||||
seed="word1 word2 ... word24",
|
||||
@@ -146,10 +146,10 @@ Go to **Settings → Backup** → copy the 24 words.
|
||||
|
||||
## 🗂️ Error Handling
|
||||
|
||||
All exceptions inherit from `FragmentError` — see [`fragmentapi/types/exceptions.py`](fragmentapi/types/exceptions.py) for the full list.
|
||||
All exceptions inherit from `FragmentError` — see [`pyfragment/types/exceptions.py`](pyfragment/types/exceptions.py) for the full list.
|
||||
|
||||
```python
|
||||
from fragmentapi import FragmentClient, UserNotFoundError, ConfigurationError, WalletError
|
||||
from pyfragment import FragmentClient, UserNotFoundError, ConfigurationError, WalletError
|
||||
|
||||
try:
|
||||
result = await client.gift_stars("@unknown", amount=100)
|
||||
|
||||
@@ -7,7 +7,7 @@ wallet_version defaults to "V5R1" — change to "V4R2" for older wallets.
|
||||
|
||||
import asyncio
|
||||
|
||||
from fragmentapi import FragmentClient
|
||||
from pyfragment import FragmentClient
|
||||
|
||||
SEED = "word1 word2 word3 word4 word5 word6 word7 word8 word9 word10 word11 word12 word13 word14 word15 word16 word17 word18 word19 word20 word21 word22 word23 word24"
|
||||
API_KEY = "YOUR_TONAPI_KEY"
|
||||
|
||||
@@ -7,7 +7,7 @@ Set show_sender=False to send anonymously.
|
||||
|
||||
import asyncio
|
||||
|
||||
from fragmentapi import ConfigurationError, FragmentClient, UserNotFoundError
|
||||
from pyfragment import ConfigurationError, FragmentClient, UserNotFoundError
|
||||
|
||||
SEED = "word1 word2 ... word24"
|
||||
API_KEY = "YOUR_TONAPI_KEY"
|
||||
|
||||
@@ -7,7 +7,7 @@ Set show_sender=False to send anonymously.
|
||||
|
||||
import asyncio
|
||||
|
||||
from fragmentapi import ConfigurationError, FragmentClient, UserNotFoundError
|
||||
from pyfragment import ConfigurationError, FragmentClient, UserNotFoundError
|
||||
|
||||
SEED = "word1 word2 ... word24"
|
||||
API_KEY = "YOUR_TONAPI_KEY"
|
||||
|
||||
@@ -7,7 +7,7 @@ Your wallet must hold at least the topup amount + ~0.056 TON for gas.
|
||||
|
||||
import asyncio
|
||||
|
||||
from fragmentapi import ConfigurationError, FragmentClient, UserNotFoundError, WalletError
|
||||
from pyfragment import ConfigurationError, FragmentClient, UserNotFoundError, WalletError
|
||||
|
||||
SEED = "word1 word2 ... word24"
|
||||
API_KEY = "YOUR_TONAPI_KEY"
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
from fragmentapi.methods.premium import gift_premium
|
||||
from fragmentapi.methods.stars import gift_stars
|
||||
from fragmentapi.methods.ton import topup_ton
|
||||
|
||||
__all__ = ["gift_premium", "gift_stars", "topup_ton"]
|
||||
@@ -3,8 +3,8 @@
|
||||
# This source code is licensed under the MIT License found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
from fragmentapi.client import FragmentClient
|
||||
from fragmentapi.types import (
|
||||
from pyfragment.client import FragmentClient
|
||||
from pyfragment.types import (
|
||||
AdsTopupResult,
|
||||
ClientError,
|
||||
ConfigurationError,
|
||||
@@ -1,9 +1,9 @@
|
||||
import json
|
||||
|
||||
from fragmentapi.methods.premium import gift_premium
|
||||
from fragmentapi.methods.stars import gift_stars
|
||||
from fragmentapi.methods.ton import topup_ton
|
||||
from fragmentapi.types import (
|
||||
from pyfragment.methods.premium import gift_premium
|
||||
from pyfragment.methods.stars import gift_stars
|
||||
from pyfragment.methods.ton import topup_ton
|
||||
from pyfragment.types import (
|
||||
REQUIRED_COOKIE_KEYS,
|
||||
SUPPORTED_WALLET_VERSIONS,
|
||||
AdsTopupResult,
|
||||
@@ -0,0 +1,5 @@
|
||||
from pyfragment.methods.premium import gift_premium
|
||||
from pyfragment.methods.stars import gift_stars
|
||||
from pyfragment.methods.ton import topup_ton
|
||||
|
||||
__all__ = ["gift_premium", "gift_stars", "topup_ton"]
|
||||
@@ -4,7 +4,7 @@ from typing import TYPE_CHECKING
|
||||
|
||||
import httpx
|
||||
|
||||
from fragmentapi.types import (
|
||||
from pyfragment.types import (
|
||||
BASE_HEADERS,
|
||||
DEVICE,
|
||||
PREMIUM_PAGE,
|
||||
@@ -15,7 +15,7 @@ from fragmentapi.types import (
|
||||
UnexpectedError,
|
||||
UserNotFoundError,
|
||||
)
|
||||
from fragmentapi.utils import (
|
||||
from pyfragment.utils import (
|
||||
execute_transaction_request,
|
||||
fragment_post,
|
||||
get_account_info,
|
||||
@@ -24,7 +24,7 @@ from fragmentapi.utils import (
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from fragmentapi.client import FragmentClient
|
||||
from pyfragment.client import FragmentClient
|
||||
|
||||
# Page-specific headers
|
||||
HEADERS: dict[str, str] = {
|
||||
@@ -3,7 +3,7 @@ from typing import TYPE_CHECKING
|
||||
|
||||
import httpx
|
||||
|
||||
from fragmentapi.types import (
|
||||
from pyfragment.types import (
|
||||
BASE_HEADERS,
|
||||
DEVICE,
|
||||
STARS_PAGE,
|
||||
@@ -14,7 +14,7 @@ from fragmentapi.types import (
|
||||
UnexpectedError,
|
||||
UserNotFoundError,
|
||||
)
|
||||
from fragmentapi.utils import (
|
||||
from pyfragment.utils import (
|
||||
execute_transaction_request,
|
||||
fragment_post,
|
||||
get_account_info,
|
||||
@@ -23,7 +23,7 @@ from fragmentapi.utils import (
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from fragmentapi.client import FragmentClient
|
||||
from pyfragment.client import FragmentClient
|
||||
|
||||
# Page-specific headers
|
||||
HEADERS: dict[str, str] = {
|
||||
@@ -3,7 +3,7 @@ from typing import TYPE_CHECKING
|
||||
|
||||
import httpx
|
||||
|
||||
from fragmentapi.types import (
|
||||
from pyfragment.types import (
|
||||
BASE_HEADERS,
|
||||
DEVICE,
|
||||
TON_PAGE,
|
||||
@@ -14,7 +14,7 @@ from fragmentapi.types import (
|
||||
UnexpectedError,
|
||||
UserNotFoundError,
|
||||
)
|
||||
from fragmentapi.utils import (
|
||||
from pyfragment.utils import (
|
||||
execute_transaction_request,
|
||||
fragment_post,
|
||||
get_account_info,
|
||||
@@ -23,7 +23,7 @@ from fragmentapi.utils import (
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from fragmentapi.client import FragmentClient
|
||||
from pyfragment.client import FragmentClient
|
||||
|
||||
# Page-specific headers
|
||||
HEADERS: dict[str, str] = {
|
||||
@@ -1,4 +1,4 @@
|
||||
from fragmentapi.types.constants import (
|
||||
from pyfragment.types.constants import (
|
||||
BASE_HEADERS,
|
||||
DEVICE,
|
||||
MIN_TON_BALANCE,
|
||||
@@ -10,7 +10,7 @@ from fragmentapi.types.constants import (
|
||||
WALLET_CLASSES,
|
||||
WalletVersion,
|
||||
)
|
||||
from fragmentapi.types.exceptions import (
|
||||
from pyfragment.types.exceptions import (
|
||||
ClientError,
|
||||
ConfigurationError,
|
||||
CookieError,
|
||||
@@ -25,7 +25,7 @@ from fragmentapi.types.exceptions import (
|
||||
VerificationError,
|
||||
WalletError,
|
||||
)
|
||||
from fragmentapi.types.results import AdsTopupResult, PremiumResult, StarsResult
|
||||
from pyfragment.types.results import AdsTopupResult, PremiumResult, StarsResult
|
||||
|
||||
__all__ = [
|
||||
# constants
|
||||
@@ -1,5 +1,5 @@
|
||||
class FragmentError(Exception):
|
||||
"""Base exception for all fragmentapi library errors."""
|
||||
"""Base exception for all pyfragment library errors."""
|
||||
|
||||
|
||||
class ClientError(FragmentError):
|
||||
@@ -1,11 +1,11 @@
|
||||
from fragmentapi.utils.decoder import clean_decode
|
||||
from fragmentapi.utils.http import (
|
||||
from pyfragment.utils.decoder import clean_decode
|
||||
from pyfragment.utils.http import (
|
||||
execute_transaction_request,
|
||||
fragment_post,
|
||||
get_fragment_hash,
|
||||
parse_json_response,
|
||||
)
|
||||
from fragmentapi.utils.wallet import get_account_info, process_transaction
|
||||
from pyfragment.utils.wallet import get_account_info, process_transaction
|
||||
|
||||
__all__ = [
|
||||
"clean_decode",
|
||||
@@ -2,7 +2,7 @@ import base64
|
||||
|
||||
from pytoniq_core import Cell
|
||||
|
||||
from fragmentapi.types import ParseError
|
||||
from pyfragment.types import ParseError
|
||||
|
||||
|
||||
def clean_decode(payload: str) -> str:
|
||||
@@ -3,7 +3,7 @@ from typing import Any
|
||||
|
||||
import httpx
|
||||
|
||||
from fragmentapi.types import FragmentPageError, ParseError, VerificationError
|
||||
from pyfragment.types import FragmentPageError, ParseError, VerificationError
|
||||
|
||||
|
||||
async def get_fragment_hash(
|
||||
@@ -4,11 +4,11 @@ from typing import TYPE_CHECKING, Any
|
||||
from tonutils.clients import TonapiClient
|
||||
from tonutils.types import NetworkGlobalID
|
||||
|
||||
from fragmentapi.types import MIN_TON_BALANCE, WALLET_CLASSES, TransactionError, WalletError
|
||||
from fragmentapi.utils.decoder import clean_decode
|
||||
from pyfragment.types import MIN_TON_BALANCE, WALLET_CLASSES, TransactionError, WalletError
|
||||
from pyfragment.utils.decoder import clean_decode
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from fragmentapi.client import FragmentClient
|
||||
from pyfragment.client import FragmentClient
|
||||
|
||||
|
||||
def _init_ton_client(client: "FragmentClient") -> TonapiClient:
|
||||
+5
-5
@@ -3,7 +3,7 @@ requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "fragmentapi"
|
||||
name = "pyfragment"
|
||||
version = "2026.1.0"
|
||||
description = "Python library for the Fragment.com API — gift Telegram Stars, Premium, and top up TON Ads balance."
|
||||
readme = "README.md"
|
||||
@@ -39,12 +39,12 @@ dev = [
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://github.com/bohd4nx/FragmentAPI"
|
||||
Repository = "https://github.com/bohd4nx/FragmentAPI"
|
||||
Issues = "https://github.com/bohd4nx/FragmentAPI/issues"
|
||||
Homepage = "https://github.com/bohd4nx/pyfragment"
|
||||
Repository = "https://github.com/bohd4nx/pyfragment"
|
||||
Issues = "https://github.com/bohd4nx/pyfragment/issues"
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["fragmentapi"]
|
||||
packages = ["pyfragment"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
testpaths = ["tests"]
|
||||
|
||||
@@ -4,8 +4,8 @@ import re
|
||||
|
||||
import pytest
|
||||
|
||||
from fragmentapi.types import ParseError
|
||||
from fragmentapi.utils.decoder import clean_decode
|
||||
from pyfragment.types import ParseError
|
||||
from pyfragment.utils.decoder import clean_decode
|
||||
|
||||
PAYLOADS = [
|
||||
pytest.param(
|
||||
|
||||
@@ -4,8 +4,8 @@ import json
|
||||
|
||||
import pytest
|
||||
|
||||
from fragmentapi import FragmentClient
|
||||
from fragmentapi.types import ConfigurationError, CookieError
|
||||
from pyfragment import FragmentClient
|
||||
from pyfragment.types import ConfigurationError, CookieError
|
||||
|
||||
VALID_SEED = "abandon " * 23 + "about"
|
||||
VALID_API_KEY = "test_api_key"
|
||||
|
||||
@@ -5,8 +5,8 @@ import re
|
||||
|
||||
import pytest
|
||||
|
||||
from fragmentapi.types import BASE_HEADERS, STARS_PAGE
|
||||
from fragmentapi.utils import get_fragment_hash
|
||||
from pyfragment.types import BASE_HEADERS, STARS_PAGE
|
||||
from pyfragment.utils import get_fragment_hash
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
||||
Reference in New Issue
Block a user