Skip to content

Commit 5116bd3

Browse files
committed
added documention and README.md and CONTRIBUTING.md
1 parent 44ce32e commit 5116bd3

File tree

5 files changed

+251
-9
lines changed

5 files changed

+251
-9
lines changed

CONTRIBUTING.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Contributing to YourPackageName
2+
3+
Thank you for considering contributing to **YourPackageName**! Contributions are what make open-source software great, and your help is highly appreciated.
4+
5+
## How to Contribute
6+
7+
### 1. Report Issues
8+
9+
If you encounter a bug, have a question, or want to suggest a feature:
10+
- Check the [issues page](https://github.com/zohal/python-zohal-sdk/issues) to see if it has already been reported.
11+
- If not, open a new issue with the following details:
12+
- **Title**: A concise description of the issue.
13+
- **Description**: Steps to reproduce the issue or the details of the feature request.
14+
- **Environment**: Include Python version, OS, and any other relevant information.
15+
16+
### 2. Submit Code Changes
17+
18+
#### Fork the Repository
19+
1. Go to the [repository](https://github.com/zohal/python-zohal-sdk) and fork it.
20+
2. Clone your fork:
21+
```bash
22+
git clone https://github.com/your_username/your_fork.git
23+
cd your_fork
24+
```
25+
26+
#### Create a Branch
27+
Create a new branch for your changes:
28+
```bash
29+
git checkout -b feature/your-feature-name
30+
```
31+
32+
#### Make Changes
33+
- Follow the project's coding style (adhering to [PEP 8](https://www.python.org/dev/peps/pep-0008/)).
34+
- Write clear and concise commit messages. Use present tense, e.g., "Add feature X."
35+
36+
#### Run Tests
37+
Ensure your changes do not break existing functionality by running the test suite:
38+
```bash
39+
pytest
40+
```
41+
If you add a new feature, include relevant tests.
42+
43+
#### Push Changes
44+
Push your changes to your forked repository:
45+
```bash
46+
git push origin feature/your-feature-name
47+
```
48+
49+
#### Open a Pull Request
50+
1. Go to the original repository and click "New Pull Request."
51+
2. Select your branch and provide a clear description of your changes.
52+
53+
54+
## Development Environment
55+
56+
To set up a local development environment:
57+
1. Clone the repository.
58+
2. Install dependencies:
59+
```bash
60+
poetry install
61+
```
62+
3. Run tests to confirm everything is working:
63+
```bash
64+
pytest
65+
```
66+
67+
## Thank You
68+
69+
Thank you for taking the time to contribute! Your efforts make this project better for everyone.

README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# zohal-sdk
2+
[![PyPi Package Version](https://img.shields.io/pypi/v/zohal-sdk.svg)](https://pypi.python.org/pypi/zohal-sdk)
3+
[![Supported Python versions](https://img.shields.io/pypi/pyversions/zohal-sdk.svg)](https://pypi.python.org/pypi/zohal-sdk)
4+
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
5+
[![PyPi status](https://img.shields.io/pypi/status/zohal-sdk.svg?style=flat-square)](https://pypi.python.org/pypi/zohal-sdk)
6+
7+
## Overview
8+
9+
zohal-sdk is a Python SDK for interfacing with [zohal.io](https://zohal.io). It simplifies the process of interacting with the API by providing clean, Pythonic abstractions for all key functionalities.
10+
11+
## Installation
12+
13+
Install the SDK using pip:
14+
15+
```bash
16+
pip install zohal-sdk
17+
```
18+
## Getting Started
19+
20+
Here's a quick example to get you started:
21+
```python
22+
from zohal_sdk import Client
23+
24+
# Initialize the client
25+
client = Client(token="your_api_key")
26+
27+
# Example usage
28+
response = client.shahkar(mobile="your mobile number", national_code="your national code")
29+
print(response)
30+
```
31+
For detailed usage, check the documentation.
32+
Documentation
33+
34+
## Documentation
35+
36+
Full documentation is available at [Documentation]().
37+
38+
## Contributing
39+
40+
We welcome contributions! See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.

zohal_sdk/client.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
""" Zohal RestAPI Client """
22
from typing import Union
3-
import io
43
from .types import RequestData
54
import logging
65

7-
from requests import Session
6+
from requests import Session, Response
87
from requests.exceptions import (Timeout, HTTPError as RHTTPError,
98
JSONDecodeError)
109

@@ -15,6 +14,12 @@
1514

1615

1716
class Client(InquiryMixin):
17+
"""
18+
Client class for zohal API
19+
20+
:param token: Token of Zohal API, should be obatined from zohal.io
21+
:raises ValueError: if token is not specified
22+
"""
1823

1924
def __init__(self, token: str):
2025
if token is None:
@@ -28,7 +33,7 @@ def request(self,
2833
url: str,
2934
data: Union[RequestData, dict, None] = None,
3035
files=None,
31-
method: str = "GET"):
36+
method: str = "GET") -> Response:
3237
logger.debug(f"request to {url=} with {method=}")
3338
try:
3439
kwargs = {"url": url, "method": method}

zohal_sdk/exceptions.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,21 @@
33

44

55
class TimeoutError(Timeout):
6+
"""
7+
Raises when api request has been timeout.
8+
"""
69
pass
710

811

912
class HTTPError(RHTTPError):
13+
"""
14+
Any HTTPError happen during requests gonna be instance of this error.
15+
"""
1016
pass
1117

1218

1319
class ZohalError(Exception):
20+
"""
21+
Internal Error or Any Error that came from zohal api.
22+
"""
1423
pass

zohal_sdk/services/inquiry.py

Lines changed: 125 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""InquiryMixin is a mixin for client to add inquiry requests"""
2+
13
from typing import Optional, Union
24
import io
35

@@ -34,6 +36,16 @@ def national_identity_inquiry(
3436
national_code: str,
3537
birth_date: str,
3638
gender: Optional[bool] = None) -> ResponseData[NationalIdentity]:
39+
"""
40+
National Identity inquiry service
41+
inquiry national_code with birth_date to see if its valid or not.
42+
43+
:param national_code: National code
44+
:param birth_date: birth date in YYYY/MM/DD format
45+
:param gender: if its true its gonna return gender otherwise it doesnt
46+
:returns: national identity data
47+
:rtype: ResponseData<NationalIdentity>
48+
"""
3749
data = NationalIdentityInqueryRequest(national_code=national_code,
3850
birth_date=birth_date,
3951
gender=gender)
@@ -45,6 +57,15 @@ def national_identity_inquiry(
4557

4658
def shahkar(self, national_code: str,
4759
mobile: str) -> ResponseData[Shahkar]:
60+
"""
61+
Shahkar
62+
inquiry mobile number with national_code to see if its valid or not.
63+
64+
:param mobile: mobile number
65+
:param national_code: national_code
66+
:returns: true if its matched.
67+
:rtype: ResponseData<Shahkar>
68+
"""
4869
data = ShahkarRequest(national_code=national_code, mobile=mobile)
4970
response = self.request(make_url(self.service_name, "shahkar"),
5071
data,
@@ -53,17 +74,37 @@ def shahkar(self, national_code: str,
5374

5475
def national_card_ocr(self, national_card_back: Union[io.FileIO, str],
5576
national_card_front: Union[io.FileIO, str]):
77+
"""
78+
National card ocr
79+
uses OCR on national card to return data of national card and photo of person from national card
80+
81+
:param national_card_front: front of national card
82+
:param national_card_back: back of national card
83+
:returns: National card data.
84+
:rtype: ResponseData<NationalCard>
85+
"""
5686
response = self.request(make_url(self.service_name,
5787
"national_card_ocr"),
5888
files={
5989
"national_card_back": national_card_back,
6090
"national_card_front": national_card_front,
61-
}, method="POST")
91+
},
92+
method="POST")
6293
return ResponseData.serialize(NationalCard, response)
6394

6495
def check_card_with_national_code(
6596
self, national_code: str, birth_date: str,
6697
card_number: str) -> ResponseData[Matched]:
98+
"""
99+
Check Card with National Code
100+
inquiry card number with national code to see if its matches or not
101+
102+
:param national_code: national code
103+
:param card_number: card number
104+
:param birth_date: birth date
105+
:returns: if matches returns true.
106+
:rtype: ResponseData<Matched>
107+
"""
67108
data = CheckCardWithNationalCodeRequest(national_code=national_code,
68109
birth_date=birth_date,
69110
card_number=card_number)
@@ -74,13 +115,29 @@ def check_card_with_national_code(
74115
return ResponseData.serialize(Matched, response)
75116

76117
def card_to_iban(self, card_number: str) -> ResponseData[IBan]:
118+
"""
119+
Card to IBan
120+
uses card_number to return IBan
121+
122+
:param card_number: card number
123+
:returns: if its successful returns iban.
124+
:rtype: ResponseData<IBan>
125+
"""
77126
data = CardToIBANRequest(card_number=card_number)
78127
response = self.request(make_url(self.service_name, "card_to_iban"),
79128
data,
80129
method="POST")
81130
return ResponseData.serialize(IBan, response)
82131

83132
def card_to_account(self, card_number: str) -> ResponseData[BankAccount]:
133+
"""
134+
Card to Account
135+
uses card_number to return account
136+
137+
:param card_number: card number
138+
:returns: if its successful returns account.
139+
:rtype: ResponseData<BankAccount>
140+
"""
84141
data = CardToAccountRequest(card_number=card_number)
85142
response = self.request(make_url(self.service_name, "card_to_account"),
86143
data,
@@ -89,46 +146,99 @@ def card_to_account(self, card_number: str) -> ResponseData[BankAccount]:
89146

90147
def iban(self,
91148
iban: str,
92-
separated: Optional[bool] = None) -> ResponseData:
149+
separated: Optional[bool] = None) -> ResponseData[IBANInquiry]:
150+
"""
151+
IBan inquiry
152+
Inquiry to check iban is valid or not
153+
154+
:param iban: iban
155+
:param separated: if its true returning name as separated
156+
:returns: if its successful returns iban.
157+
:rtype: ResponseData<IBANInquiry>
158+
"""
93159
data = IBANRequest(iban=iban, separated=separated)
94160
response = self.request(make_url(self.service_name, "iban"),
95161
data,
96162
method="POST")
97163
return ResponseData.serialize(IBANInquiry, response)
98164

99165
def card_inquiry(self, card_number) -> ResponseData:
166+
"""
167+
card inquiry
168+
Inquiry to check card is valid or not
169+
170+
:param card_number: card number
171+
:returns: if its successful returns Card.
172+
:rtype: ResponseData<Card>
173+
"""
100174
data = CardInquiryRequest(card_number=card_number)
101175
response = self.request(make_url(self.service_name, "card_inquiry"),
102176
data,
103177
method="POST")
104178
return ResponseData.serialize(Card, response)
105179

106180
def check_card_with_name(self, card_number: str,
107-
name: str) -> ResponseData:
181+
name: str) -> ResponseData[Matched]:
182+
"""
183+
check card with name
184+
Inquiry to check card with name it matches or not
185+
186+
:param card_number: card number
187+
:param name: name
188+
:returns: if it matches returns true.
189+
:rtype: ResponseData<Matched>
190+
"""
108191
data = CheckCardWithNameRequest(card_number=card_number, name=name)
109192
response = self.request(make_url(self.service_name,
110193
"check_card_with_name"),
111194
data,
112195
method="POST")
113196
return ResponseData.serialize(Matched, response)
114197

115-
def check_iban_with_name(self, iban: str, name: str) -> ResponseData:
198+
def check_iban_with_name(self, iban: str,
199+
name: str) -> ResponseData[Matched]:
200+
"""
201+
check iban with name
202+
Inquiry to check iban with name it matches or not
203+
204+
:param iban: Iban
205+
:param name: name
206+
:returns: if it matches returns true.
207+
:rtype: ResponseData<Matched>
208+
"""
116209
data = CheckIBANWithNameRequest(IBAN=iban, name=name)
117210
response = self.request(make_url(self.service_name,
118211
"check_iban_with_name"),
119212
data,
120213
method="POST")
121214
return ResponseData.serialize(Matched, response)
122215

123-
def postal_code_inquiry(self, postal_code: str) -> ResponseData:
216+
def postal_code_inquiry(self,
217+
postal_code: str) -> ResponseData[PostalCode]:
218+
"""
219+
postal code inquiry
220+
Inquiry to retrive postal code data
221+
222+
:param postal_code: Postal code
223+
:returns: if its ok returns data of that postal_code.
224+
:rtype: ResponseData<PostalCode>
225+
"""
124226
data = PostalCodeInquiry(postal_code=postal_code)
125227
response = self.request(make_url(self.service_name,
126228
"postal_code_inquiry"),
127229
data,
128230
method="POST")
129231
return ResponseData.serialize(PostalCode, response)
130232

131-
def persian_to_finglish(self, persian_text: str) -> ResponseData:
233+
def persian_to_finglish(self, persian_text: str) -> ResponseData[Finglish]:
234+
"""
235+
persian to finglish
236+
transform persian text to finglish text
237+
238+
:param persian_text: Persian text
239+
:returns: if its successful returns finglish text.
240+
:rtype: ResponseData<Finglish>
241+
"""
132242
data = PersianToFinglishRequest(persian_text=persian_text)
133243
response = self.request(make_url(self.service_name,
134244
"persian_to_finglish"),
@@ -138,6 +248,15 @@ def persian_to_finglish(self, persian_text: str) -> ResponseData:
138248

139249
def account_to_iban(self, bank_account: str,
140250
bank_code: BankCode) -> ResponseData[IBan]:
251+
"""
252+
account to iban
253+
Inquiry to retrive iban from bank_account
254+
255+
:param bank_account: account number
256+
:param bank_code: BankCode
257+
:returns: returns Iban data.
258+
:rtype: ResponseData<IBan>
259+
"""
141260
data = AccountToIBANRequest(bank_account=bank_account,
142261
bank_code=bank_code)
143262
response = self.request(make_url(self.service_name, "account_to_iban"),

0 commit comments

Comments
 (0)