letit 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- letit-0.0.1/LICENSE +21 -0
- letit-0.0.1/PKG-INFO +136 -0
- letit-0.0.1/README.md +126 -0
- letit-0.0.1/letit/__init__.py +3 -0
- letit-0.0.1/letit/client.py +39 -0
- letit-0.0.1/letit/resources/__init__.py +0 -0
- letit-0.0.1/letit/resources/job.py +118 -0
- letit-0.0.1/letit/resources/micropost.py +89 -0
- letit-0.0.1/letit/schemas/__init__.py +0 -0
- letit-0.0.1/letit/schemas/common.py +5 -0
- letit-0.0.1/letit/schemas/job.py +53 -0
- letit-0.0.1/letit/schemas/micropost.py +6 -0
- letit-0.0.1/letit/settings.py +1 -0
- letit-0.0.1/letit/tests/test_letit_integration.py +46 -0
- letit-0.0.1/letit/tests/test_letit_unit.py +52 -0
- letit-0.0.1/letit.egg-info/PKG-INFO +136 -0
- letit-0.0.1/letit.egg-info/SOURCES.txt +20 -0
- letit-0.0.1/letit.egg-info/dependency_links.txt +1 -0
- letit-0.0.1/letit.egg-info/requires.txt +1 -0
- letit-0.0.1/letit.egg-info/top_level.txt +1 -0
- letit-0.0.1/pyproject.toml +18 -0
- letit-0.0.1/setup.cfg +4 -0
letit-0.0.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 LetIt https://www.letit.com support@letit.com
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
letit-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: letit
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Python SDK for the LetIt API
|
|
5
|
+
Requires-Python: >=3.9
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Dist: requests>=2.32.0
|
|
9
|
+
Dynamic: license-file
|
|
10
|
+
|
|
11
|
+
# LetIt Python
|
|
12
|
+
|
|
13
|
+
The official Python SDK for the [LetIt](https://letit.com) API.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install letit
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Setup
|
|
22
|
+
|
|
23
|
+
Find your API token at [https://letit.com/settings/developer](https://letit.com/settings/developer) after creating an account at [https://letit.com/register](https://letit.com/register).
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from letit import LetIt
|
|
27
|
+
|
|
28
|
+
client = LetIt(api_token="your_api_token_here")
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
### Create a micropost
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from letit.schemas.micropost import PostType
|
|
37
|
+
|
|
38
|
+
# Text post
|
|
39
|
+
post = client.micropost.client_create_micropost(
|
|
40
|
+
title="Hello World",
|
|
41
|
+
body="This is my first post.",
|
|
42
|
+
)
|
|
43
|
+
print(post.public_id)
|
|
44
|
+
print(post.link)
|
|
45
|
+
|
|
46
|
+
# Media post
|
|
47
|
+
with open("photo.png", "rb") as f:
|
|
48
|
+
post = client.micropost.client_create_micropost(
|
|
49
|
+
title="My photo",
|
|
50
|
+
body="Check this out",
|
|
51
|
+
post_type=PostType.MEDIA,
|
|
52
|
+
file=("photo.png", f, "image/png"),
|
|
53
|
+
)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Create a job post
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from letit.schemas.job import JobLocation, JobType, JobCategory, JobExperienceLevel
|
|
60
|
+
|
|
61
|
+
job = client.job.client_create_user_job_with_company(
|
|
62
|
+
company_name="LetIt",
|
|
63
|
+
company_description="We build things.",
|
|
64
|
+
company_website="https://letit.com",
|
|
65
|
+
job_title="Rust Engineer",
|
|
66
|
+
job_description="Build backend services in Rust.",
|
|
67
|
+
job_how_to_apply="https://letit.com/careers",
|
|
68
|
+
job_location=JobLocation.REMOTE,
|
|
69
|
+
job_type=JobType.FULLTIME,
|
|
70
|
+
job_category=JobCategory.PROGRAMMING,
|
|
71
|
+
job_experience_level=JobExperienceLevel.SENIOR,
|
|
72
|
+
job_skills="Rust, SQL",
|
|
73
|
+
)
|
|
74
|
+
print(job.slug)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## API Reference
|
|
78
|
+
|
|
79
|
+
### `LetIt(api_token, base_url?)`
|
|
80
|
+
|
|
81
|
+
| Parameter | Type | Description |
|
|
82
|
+
|-----------|------|-------------|
|
|
83
|
+
| `api_token` | `str` | Your API token |
|
|
84
|
+
| `base_url` | `str` | API base URL (default: `https://api.letit.com`) |
|
|
85
|
+
|
|
86
|
+
### `client.micropost.client_create_micropost(...)`
|
|
87
|
+
|
|
88
|
+
| Parameter | Type | Default | Description |
|
|
89
|
+
|-----------|------|---------|-------------|
|
|
90
|
+
| `body` | `str` | required | Content of the post |
|
|
91
|
+
| `title` | `str` | `None` | Required for original posts |
|
|
92
|
+
| `post_type` | `PostType` | `PostType.TEXT` | `PostType.TEXT` or `PostType.MEDIA` |
|
|
93
|
+
| `community_name` | `str` | `None` | Community to post in |
|
|
94
|
+
| `parent_micropost_public_id` | `str` | `None` | For replies |
|
|
95
|
+
| `parent_micropost_comment_public_id` | `str` | `None` | For nested replies |
|
|
96
|
+
| `allow_comments` | `bool` | `True` | Whether comments are allowed |
|
|
97
|
+
| `is_draft` | `bool` | `False` | Save as draft |
|
|
98
|
+
| `file` | `tuple` | `None` | `(filename, file_object, mime_type)` for MEDIA posts |
|
|
99
|
+
|
|
100
|
+
### `client.job.client_create_user_job_with_company(...)`
|
|
101
|
+
|
|
102
|
+
| Parameter | Type | Default | Description |
|
|
103
|
+
|-----------|------|---------|-------------|
|
|
104
|
+
| `company_name` | `str` | required | Name of the company |
|
|
105
|
+
| `company_description` | `str` | required | Description of the company |
|
|
106
|
+
| `company_website` | `str` | required | Company website URL |
|
|
107
|
+
| `job_title` | `str` | required | Title of the job |
|
|
108
|
+
| `job_description` | `str` | required | Full job description |
|
|
109
|
+
| `job_how_to_apply` | `str` | required | URL or instructions to apply |
|
|
110
|
+
| `company_logo` | `tuple` | `None` | `(filename, file_object, mime_type)` |
|
|
111
|
+
| `company_location` | `str` | `None` | Company location |
|
|
112
|
+
| `job_location` | `JobLocation` | `JobLocation.REMOTE` | `REMOTE`, `ONSITE`, `HYBRID` |
|
|
113
|
+
| `job_type` | `JobType` | `JobType.FULLTIME` | `FULLTIME`, `PARTTIME`, `CONTRACT`, `FREELANCE`, `INTERNSHIP` |
|
|
114
|
+
| `job_category` | `JobCategory` | `JobCategory.PROGRAMMING` | `PROGRAMMING`, `BLOCKCHAIN`, `DESIGN`, `MARKETING`, `CUSTOMERSUPPORT`, `WRITING`, `PRODUCT`, `SERVICE`, `HUMANRESOURCE`, `ELSE` |
|
|
115
|
+
| `job_experience_level` | `JobExperienceLevel` | `JobExperienceLevel.ALL` | `ALL`, `JUNIOR`, `MID`, `SENIOR`, `NOEXPERIENCEREQUIRED` |
|
|
116
|
+
| `job_minimum_salary` | `int` | `None` | Minimum salary |
|
|
117
|
+
| `job_maximum_salary` | `int` | `None` | Maximum salary |
|
|
118
|
+
| `job_pay_in_cryptocurrency` | `bool` | `False` | Pay in cryptocurrency |
|
|
119
|
+
| `job_skills` | `str` | `None` | Comma-separated skills |
|
|
120
|
+
|
|
121
|
+
## Development
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Install in editable mode
|
|
125
|
+
pip install -e .
|
|
126
|
+
|
|
127
|
+
# Run unit tests
|
|
128
|
+
python -m pytest letit/tests/test_letit.py -v
|
|
129
|
+
|
|
130
|
+
# Run integration tests (requires real API token)
|
|
131
|
+
LETIT_API_TOKEN=your_token python -m pytest letit/tests/test_letit_integration.py -v -s
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## License
|
|
135
|
+
|
|
136
|
+
MIT
|
letit-0.0.1/README.md
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# LetIt Python
|
|
2
|
+
|
|
3
|
+
The official Python SDK for the [LetIt](https://letit.com) API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install letit
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
Find your API token at [https://letit.com/settings/developer](https://letit.com/settings/developer) after creating an account at [https://letit.com/register](https://letit.com/register).
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from letit import LetIt
|
|
17
|
+
|
|
18
|
+
client = LetIt(api_token="your_api_token_here")
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
### Create a micropost
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from letit.schemas.micropost import PostType
|
|
27
|
+
|
|
28
|
+
# Text post
|
|
29
|
+
post = client.micropost.client_create_micropost(
|
|
30
|
+
title="Hello World",
|
|
31
|
+
body="This is my first post.",
|
|
32
|
+
)
|
|
33
|
+
print(post.public_id)
|
|
34
|
+
print(post.link)
|
|
35
|
+
|
|
36
|
+
# Media post
|
|
37
|
+
with open("photo.png", "rb") as f:
|
|
38
|
+
post = client.micropost.client_create_micropost(
|
|
39
|
+
title="My photo",
|
|
40
|
+
body="Check this out",
|
|
41
|
+
post_type=PostType.MEDIA,
|
|
42
|
+
file=("photo.png", f, "image/png"),
|
|
43
|
+
)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Create a job post
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from letit.schemas.job import JobLocation, JobType, JobCategory, JobExperienceLevel
|
|
50
|
+
|
|
51
|
+
job = client.job.client_create_user_job_with_company(
|
|
52
|
+
company_name="LetIt",
|
|
53
|
+
company_description="We build things.",
|
|
54
|
+
company_website="https://letit.com",
|
|
55
|
+
job_title="Rust Engineer",
|
|
56
|
+
job_description="Build backend services in Rust.",
|
|
57
|
+
job_how_to_apply="https://letit.com/careers",
|
|
58
|
+
job_location=JobLocation.REMOTE,
|
|
59
|
+
job_type=JobType.FULLTIME,
|
|
60
|
+
job_category=JobCategory.PROGRAMMING,
|
|
61
|
+
job_experience_level=JobExperienceLevel.SENIOR,
|
|
62
|
+
job_skills="Rust, SQL",
|
|
63
|
+
)
|
|
64
|
+
print(job.slug)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## API Reference
|
|
68
|
+
|
|
69
|
+
### `LetIt(api_token, base_url?)`
|
|
70
|
+
|
|
71
|
+
| Parameter | Type | Description |
|
|
72
|
+
|-----------|------|-------------|
|
|
73
|
+
| `api_token` | `str` | Your API token |
|
|
74
|
+
| `base_url` | `str` | API base URL (default: `https://api.letit.com`) |
|
|
75
|
+
|
|
76
|
+
### `client.micropost.client_create_micropost(...)`
|
|
77
|
+
|
|
78
|
+
| Parameter | Type | Default | Description |
|
|
79
|
+
|-----------|------|---------|-------------|
|
|
80
|
+
| `body` | `str` | required | Content of the post |
|
|
81
|
+
| `title` | `str` | `None` | Required for original posts |
|
|
82
|
+
| `post_type` | `PostType` | `PostType.TEXT` | `PostType.TEXT` or `PostType.MEDIA` |
|
|
83
|
+
| `community_name` | `str` | `None` | Community to post in |
|
|
84
|
+
| `parent_micropost_public_id` | `str` | `None` | For replies |
|
|
85
|
+
| `parent_micropost_comment_public_id` | `str` | `None` | For nested replies |
|
|
86
|
+
| `allow_comments` | `bool` | `True` | Whether comments are allowed |
|
|
87
|
+
| `is_draft` | `bool` | `False` | Save as draft |
|
|
88
|
+
| `file` | `tuple` | `None` | `(filename, file_object, mime_type)` for MEDIA posts |
|
|
89
|
+
|
|
90
|
+
### `client.job.client_create_user_job_with_company(...)`
|
|
91
|
+
|
|
92
|
+
| Parameter | Type | Default | Description |
|
|
93
|
+
|-----------|------|---------|-------------|
|
|
94
|
+
| `company_name` | `str` | required | Name of the company |
|
|
95
|
+
| `company_description` | `str` | required | Description of the company |
|
|
96
|
+
| `company_website` | `str` | required | Company website URL |
|
|
97
|
+
| `job_title` | `str` | required | Title of the job |
|
|
98
|
+
| `job_description` | `str` | required | Full job description |
|
|
99
|
+
| `job_how_to_apply` | `str` | required | URL or instructions to apply |
|
|
100
|
+
| `company_logo` | `tuple` | `None` | `(filename, file_object, mime_type)` |
|
|
101
|
+
| `company_location` | `str` | `None` | Company location |
|
|
102
|
+
| `job_location` | `JobLocation` | `JobLocation.REMOTE` | `REMOTE`, `ONSITE`, `HYBRID` |
|
|
103
|
+
| `job_type` | `JobType` | `JobType.FULLTIME` | `FULLTIME`, `PARTTIME`, `CONTRACT`, `FREELANCE`, `INTERNSHIP` |
|
|
104
|
+
| `job_category` | `JobCategory` | `JobCategory.PROGRAMMING` | `PROGRAMMING`, `BLOCKCHAIN`, `DESIGN`, `MARKETING`, `CUSTOMERSUPPORT`, `WRITING`, `PRODUCT`, `SERVICE`, `HUMANRESOURCE`, `ELSE` |
|
|
105
|
+
| `job_experience_level` | `JobExperienceLevel` | `JobExperienceLevel.ALL` | `ALL`, `JUNIOR`, `MID`, `SENIOR`, `NOEXPERIENCEREQUIRED` |
|
|
106
|
+
| `job_minimum_salary` | `int` | `None` | Minimum salary |
|
|
107
|
+
| `job_maximum_salary` | `int` | `None` | Maximum salary |
|
|
108
|
+
| `job_pay_in_cryptocurrency` | `bool` | `False` | Pay in cryptocurrency |
|
|
109
|
+
| `job_skills` | `str` | `None` | Comma-separated skills |
|
|
110
|
+
|
|
111
|
+
## Development
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# Install in editable mode
|
|
115
|
+
pip install -e .
|
|
116
|
+
|
|
117
|
+
# Run unit tests
|
|
118
|
+
python -m pytest letit/tests/test_letit.py -v
|
|
119
|
+
|
|
120
|
+
# Run integration tests (requires real API token)
|
|
121
|
+
LETIT_API_TOKEN=your_token python -m pytest letit/tests/test_letit_integration.py -v -s
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## License
|
|
125
|
+
|
|
126
|
+
MIT
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# $pip freeze > requirements.txt
|
|
2
|
+
# $pip install -r requirements.txt
|
|
3
|
+
|
|
4
|
+
from letit.settings import DEFAULT_API_SERVER
|
|
5
|
+
from letit.resources.micropost import MicropostResource
|
|
6
|
+
from letit.resources.job import JobResource
|
|
7
|
+
import requests
|
|
8
|
+
|
|
9
|
+
class LetIt:
|
|
10
|
+
"""
|
|
11
|
+
Client for the LetIt API.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
api_token: Your API token. Generate one at https://letit.com/settings/developer
|
|
15
|
+
base_url: Base URL for the API. Defaults to the standard LetIt API server.
|
|
16
|
+
|
|
17
|
+
Example:
|
|
18
|
+
client = LetIt(api_token="your_token_here")
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
api_token: str,
|
|
24
|
+
base_url: str = DEFAULT_API_SERVER,
|
|
25
|
+
) -> None:
|
|
26
|
+
self.api_token = api_token
|
|
27
|
+
self.base_url = base_url
|
|
28
|
+
self._headers = {"USER-API-TOKEN": api_token}
|
|
29
|
+
|
|
30
|
+
self.micropost = MicropostResource(self)
|
|
31
|
+
self.job = JobResource(self)
|
|
32
|
+
|
|
33
|
+
def _request(self, method: str, path: str, **kwargs) -> requests.Response:
|
|
34
|
+
url = f"{self.base_url}{path}"
|
|
35
|
+
extra_headers = kwargs.pop("headers", {})
|
|
36
|
+
headers = {**self._headers, **extra_headers}
|
|
37
|
+
response = requests.request(method, url, headers=headers, **kwargs)
|
|
38
|
+
response.raise_for_status()
|
|
39
|
+
return response
|
|
File without changes
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# letit/resources/job.py
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import TYPE_CHECKING, Optional
|
|
5
|
+
from requests_toolbelt.multipart.encoder import MultipartEncoder
|
|
6
|
+
|
|
7
|
+
# import sys
|
|
8
|
+
# import os
|
|
9
|
+
# sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
10
|
+
|
|
11
|
+
from letit.schemas.job import JobCategory, JobExperienceLevel, JobLocation, JobType, UserJobCreatedByUserResponse
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from ..client import Letit
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class JobResponse:
|
|
19
|
+
slug: str
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def from_dict(cls, data: dict) -> "JobResponse":
|
|
23
|
+
return cls(slug=data["slug"])
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class JobResource:
|
|
27
|
+
def __init__(self, client: "Letit"):
|
|
28
|
+
self._client = client
|
|
29
|
+
|
|
30
|
+
def client_create_user_job_with_company(
|
|
31
|
+
self,
|
|
32
|
+
company_name: str,
|
|
33
|
+
company_description: str,
|
|
34
|
+
company_logo: tuple, # ("logo.png", open(..., "rb"), "image/png")
|
|
35
|
+
company_website: str,
|
|
36
|
+
job_title: str,
|
|
37
|
+
job_description: str,
|
|
38
|
+
job_how_to_apply: str,
|
|
39
|
+
company_location: Optional[str] = None,
|
|
40
|
+
job_location: JobLocation = JobLocation.REMOTE,
|
|
41
|
+
job_type: JobType = JobType.FULLTIME,
|
|
42
|
+
job_category: JobCategory = JobCategory.PROGRAMMING,
|
|
43
|
+
job_experience_level: JobExperienceLevel = JobExperienceLevel.ALL,
|
|
44
|
+
job_minimum_salary: Optional[int] = None,
|
|
45
|
+
job_maximum_salary: Optional[int] = None,
|
|
46
|
+
job_pay_in_cryptocurrency: bool = False,
|
|
47
|
+
job_skills: Optional[str] = None,
|
|
48
|
+
) -> UserJobCreatedByUserResponse:
|
|
49
|
+
"""
|
|
50
|
+
Create a job post with a company.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
company_name: Name of the company.
|
|
54
|
+
company_description: Description of the company.
|
|
55
|
+
company_logo: Tuple of (filename, file_object, mime_type). Optional.
|
|
56
|
+
company_website: Company website URL.
|
|
57
|
+
job_title: Title of the job.
|
|
58
|
+
job_description: Full job description.
|
|
59
|
+
job_how_to_apply: URL or instructions to apply.
|
|
60
|
+
company_location: Optional company location.
|
|
61
|
+
job_location: Defaults to JobLocation.REMOTE.
|
|
62
|
+
job_type: Defaults to JobType.FULLTIME.
|
|
63
|
+
job_category: Defaults to JobCategory.PROGRAMMING.
|
|
64
|
+
job_experience_level: Defaults to JobExperienceLevel.ALL.
|
|
65
|
+
job_minimum_salary: Optional minimum salary.
|
|
66
|
+
job_maximum_salary: Optional maximum salary.
|
|
67
|
+
job_pay_in_cryptocurrency: Defaults to False.
|
|
68
|
+
job_skills: Comma-separated skills string.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
UserJobCreatedByUserResponse with slug.
|
|
72
|
+
|
|
73
|
+
Example:
|
|
74
|
+
job = client.job.client_create_user_job_with_company(
|
|
75
|
+
company_name="LetIt",
|
|
76
|
+
company_description="We build things.",
|
|
77
|
+
company_website="https://letit.com",
|
|
78
|
+
job_title="Rust Engineer",
|
|
79
|
+
job_description="Build backend services.",
|
|
80
|
+
job_how_to_apply="https://letit.com/careers",
|
|
81
|
+
job_skills="Rust, SQL, Docker",
|
|
82
|
+
)
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
fields = {
|
|
86
|
+
"company_name": company_name,
|
|
87
|
+
"company_description": company_description,
|
|
88
|
+
"company_website": company_website,
|
|
89
|
+
"job_title": job_title,
|
|
90
|
+
"job_description": job_description,
|
|
91
|
+
"job_how_to_apply": job_how_to_apply,
|
|
92
|
+
"job_location": job_location,
|
|
93
|
+
"job_type": job_type,
|
|
94
|
+
"job_category": job_category,
|
|
95
|
+
"job_experience_level": job_experience_level,
|
|
96
|
+
"job_pay_in_cryptocurrency": str(job_pay_in_cryptocurrency).lower(),
|
|
97
|
+
"company_logo": company_logo,
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if company_location:
|
|
101
|
+
fields["company_location"] = company_location
|
|
102
|
+
if job_minimum_salary is not None:
|
|
103
|
+
fields["job_minimum_salary"] = str(job_minimum_salary)
|
|
104
|
+
if job_maximum_salary is not None:
|
|
105
|
+
fields["job_maximum_salary"] = str(job_maximum_salary)
|
|
106
|
+
if job_skills:
|
|
107
|
+
fields["job_skills"] = job_skills
|
|
108
|
+
|
|
109
|
+
m = MultipartEncoder(fields=fields)
|
|
110
|
+
|
|
111
|
+
response = self._client._request(
|
|
112
|
+
"POST",
|
|
113
|
+
"/api/v1/client/job",
|
|
114
|
+
data=m,
|
|
115
|
+
headers={"Content-Type": m.content_type},
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
return UserJobCreatedByUserResponse(**response.json())
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import TYPE_CHECKING, Optional
|
|
3
|
+
from requests_toolbelt.multipart.encoder import MultipartEncoder
|
|
4
|
+
|
|
5
|
+
# import sys
|
|
6
|
+
# import os
|
|
7
|
+
# sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
8
|
+
|
|
9
|
+
from letit.schemas.micropost import PostType
|
|
10
|
+
from letit.schemas.common import CreatedWithPublicIdAndLinkResponse
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from ..client import LetIt
|
|
14
|
+
|
|
15
|
+
class MicropostResource:
|
|
16
|
+
def __init__(self, client: "LetIt"):
|
|
17
|
+
self._client = client
|
|
18
|
+
|
|
19
|
+
def client_create_micropost(
|
|
20
|
+
self,
|
|
21
|
+
body: str,
|
|
22
|
+
title: Optional[str] = None,
|
|
23
|
+
post_type: PostType = PostType.TEXT,
|
|
24
|
+
community_name: Optional[str] = None,
|
|
25
|
+
parent_micropost_public_id: Optional[str] = None,
|
|
26
|
+
parent_micropost_comment_public_id: Optional[str] = None,
|
|
27
|
+
allow_comments: bool = True,
|
|
28
|
+
is_draft: bool = False,
|
|
29
|
+
file: Optional[tuple] = None, # ("filename.png", open(..., "rb"), "image/png")
|
|
30
|
+
) -> CreatedWithPublicIdAndLinkResponse:
|
|
31
|
+
"""
|
|
32
|
+
A client creates a micropost.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
body: The content of the post.
|
|
36
|
+
title: Required for original posts.
|
|
37
|
+
post_type: "TEXT" or "MEDIA". Defaults to "TEXT".
|
|
38
|
+
community_name: Optional community to post in.
|
|
39
|
+
parent_micropost_public_id: For replies.
|
|
40
|
+
parent_micropost_comment_public_id: For nested replies.
|
|
41
|
+
allow_comments: Whether comments are allowed. Defaults to True.
|
|
42
|
+
is_draft: Save as draft. Defaults to False.
|
|
43
|
+
file: Tuple of (filename, file_object, mime_type) for MEDIA posts.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
MicropostResponse with public_id and link.
|
|
47
|
+
|
|
48
|
+
Example:
|
|
49
|
+
# Text post
|
|
50
|
+
post = client.micropost.create(title="Hello", body="World")
|
|
51
|
+
|
|
52
|
+
# Media post
|
|
53
|
+
with open("photo.png", "rb") as f:
|
|
54
|
+
post = client.micropost.create(
|
|
55
|
+
title="My photo",
|
|
56
|
+
body="Check this out",
|
|
57
|
+
post_type="MEDIA",
|
|
58
|
+
file=("photo.png", f, "image/png"),
|
|
59
|
+
)
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
fields = {
|
|
63
|
+
"body": body,
|
|
64
|
+
"post_type": post_type,
|
|
65
|
+
"allow_comments": str(allow_comments).lower(),
|
|
66
|
+
"is_draft": str(is_draft).lower(),
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if title:
|
|
70
|
+
fields["title"] = title
|
|
71
|
+
if community_name:
|
|
72
|
+
fields["community_name"] = community_name
|
|
73
|
+
if parent_micropost_public_id:
|
|
74
|
+
fields["parent_micropost_public_id"] = parent_micropost_public_id
|
|
75
|
+
if parent_micropost_comment_public_id:
|
|
76
|
+
fields["parent_micropost_comment_public_id"] = parent_micropost_comment_public_id
|
|
77
|
+
if file:
|
|
78
|
+
fields["file"] = file # tuple: ("filename.png", open(...), "image/png")
|
|
79
|
+
|
|
80
|
+
m = MultipartEncoder(fields=fields)
|
|
81
|
+
|
|
82
|
+
response = self._client._request(
|
|
83
|
+
"POST",
|
|
84
|
+
"/api/v1/client/micropost",
|
|
85
|
+
data=m,
|
|
86
|
+
headers={"Content-Type": m.content_type},
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
return CreatedWithPublicIdAndLinkResponse(**response.json())
|
|
File without changes
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from enum import Enum, unique
|
|
2
|
+
from pydantic import BaseModel
|
|
3
|
+
|
|
4
|
+
@unique
|
|
5
|
+
class JobLocation(str, Enum):
|
|
6
|
+
REMOTE = "REMOTE"
|
|
7
|
+
ONSITE = "ONSITE"
|
|
8
|
+
HYBRID = "HYBRID"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@unique
|
|
12
|
+
class JobType(str, Enum):
|
|
13
|
+
FULLTIME = "FULLTIME"
|
|
14
|
+
PARTTIME = "PARTTIME"
|
|
15
|
+
CONTRACT = "CONTRACT"
|
|
16
|
+
FREELANCE = "FREELANCE"
|
|
17
|
+
INTERNSHIP = "INTERNSHIP"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@unique
|
|
21
|
+
class JobCategory(str, Enum):
|
|
22
|
+
PROGRAMMING = "PROGRAMMING"
|
|
23
|
+
BLOCKCHAIN = "BLOCKCHAIN"
|
|
24
|
+
DESIGN = "DESIGN"
|
|
25
|
+
MARKETING = "MARKETING"
|
|
26
|
+
CUSTOMERSUPPORT = "CUSTOMERSUPPORT"
|
|
27
|
+
WRITING = "WRITING"
|
|
28
|
+
PRODUCT = "PRODUCT"
|
|
29
|
+
SERVICE = "SERVICE"
|
|
30
|
+
HUMANRESOURCE = "HUMANRESOURCE"
|
|
31
|
+
ELSE = "ELSE"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@unique
|
|
35
|
+
class JobExperienceLevel(str, Enum):
|
|
36
|
+
ALL = "ALL"
|
|
37
|
+
JUNIOR = "JUNIOR"
|
|
38
|
+
MID = "MID"
|
|
39
|
+
SENIOR = "SENIOR"
|
|
40
|
+
NOEXPERIENCEREQUIRED = "NOEXPERIENCEREQUIRED"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@unique
|
|
44
|
+
class JobStatus(str, Enum):
|
|
45
|
+
DRAFT = "DRAFT"
|
|
46
|
+
PAID = "PAID"
|
|
47
|
+
CONFIRMED = "CONFIRMED"
|
|
48
|
+
HOLD = "HOLD"
|
|
49
|
+
REVIEW = "REVIEW"
|
|
50
|
+
CLOSED = "CLOSED"
|
|
51
|
+
|
|
52
|
+
class UserJobCreatedByUserResponse(BaseModel):
|
|
53
|
+
slug: str
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
DEFAULT_API_SERVER = "https://api.letit.com"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Unit tests
|
|
2
|
+
|
|
3
|
+
import httpx
|
|
4
|
+
import pytest
|
|
5
|
+
from unittest.mock import MagicMock, patch
|
|
6
|
+
|
|
7
|
+
import sys
|
|
8
|
+
import os
|
|
9
|
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
10
|
+
|
|
11
|
+
from client import LetIt
|
|
12
|
+
|
|
13
|
+
# $pip install -e .
|
|
14
|
+
# $LETIT_API_TOKEN=yours python -m pytest letit/tests/test_letit_integration.py -v -s
|
|
15
|
+
# @pytest.mark.skip(reason="already tested")
|
|
16
|
+
def test_client_create_micropost():
|
|
17
|
+
client = LetIt(api_token=os.environ["LETIT_API_TOKEN"])
|
|
18
|
+
try:
|
|
19
|
+
response = client.micropost.client_create_micropost(title="Test", body="Hello")
|
|
20
|
+
assert response.public_id is not None
|
|
21
|
+
except Exception as e:
|
|
22
|
+
if hasattr(e, 'response'):
|
|
23
|
+
print(repr(e.response.text))
|
|
24
|
+
raise
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@pytest.mark.skip(reason="already tested")
|
|
28
|
+
def test_create_user_job_with_company():
|
|
29
|
+
client = LetIt(api_token=os.environ["LETIT_API_TOKEN"])
|
|
30
|
+
try:
|
|
31
|
+
with open("letit/tests/test_logo.png", "rb") as f:
|
|
32
|
+
response = client.job.client_create_user_job_with_company(
|
|
33
|
+
company_name="LetIt",
|
|
34
|
+
company_description="A test company.",
|
|
35
|
+
company_logo=("logo.png", f, "image/png"),
|
|
36
|
+
company_website="https://letit.com",
|
|
37
|
+
job_title="Test Engineers",
|
|
38
|
+
job_description="Write tests all day.",
|
|
39
|
+
job_how_to_apply="https://letit.com/apply",
|
|
40
|
+
job_skills="Python, pytest",
|
|
41
|
+
)
|
|
42
|
+
assert response.slug is not None
|
|
43
|
+
except Exception as e:
|
|
44
|
+
if hasattr(e, 'response'):
|
|
45
|
+
print(repr(e.response.text))
|
|
46
|
+
raise
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Unit tests
|
|
2
|
+
|
|
3
|
+
import httpx
|
|
4
|
+
import pytest
|
|
5
|
+
from unittest.mock import MagicMock, patch
|
|
6
|
+
|
|
7
|
+
import sys
|
|
8
|
+
import os
|
|
9
|
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
10
|
+
|
|
11
|
+
from client import LetIt
|
|
12
|
+
from settings import DEFAULT_API_SERVER
|
|
13
|
+
|
|
14
|
+
# $pip install -e .
|
|
15
|
+
# $pytest letit/tests/test_letit_unit.py -v
|
|
16
|
+
@pytest.fixture
|
|
17
|
+
def client():
|
|
18
|
+
return LetIt(api_token="test_token")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_init(client):
|
|
22
|
+
assert client.api_token == "test_token"
|
|
23
|
+
assert client._headers == {"USER-API-TOKEN": "test_token"}
|
|
24
|
+
assert client.base_url == DEFAULT_API_SERVER
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@patch("letit.client.httpx.request")
|
|
28
|
+
def test_request_success(mock_request, client):
|
|
29
|
+
mock_response = MagicMock()
|
|
30
|
+
mock_response.status_code = 200
|
|
31
|
+
mock_request.return_value = mock_response
|
|
32
|
+
|
|
33
|
+
response = client._request("GET", "/some/path")
|
|
34
|
+
|
|
35
|
+
mock_request.assert_called_once_with(
|
|
36
|
+
"GET",
|
|
37
|
+
f"{DEFAULT_API_SERVER}/some/path",
|
|
38
|
+
headers={"USER-API-TOKEN": "test_token"},
|
|
39
|
+
)
|
|
40
|
+
assert response == mock_response
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@patch("letit.client.httpx.request")
|
|
44
|
+
def test_request_raises_on_error(mock_request, client):
|
|
45
|
+
mock_response = MagicMock()
|
|
46
|
+
mock_response.raise_for_status.side_effect = httpx.HTTPStatusError(
|
|
47
|
+
"404", request=MagicMock(), response=mock_response
|
|
48
|
+
)
|
|
49
|
+
mock_request.return_value = mock_response
|
|
50
|
+
|
|
51
|
+
with pytest.raises(httpx.HTTPStatusError):
|
|
52
|
+
client._request("GET", "/bad/path")
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: letit
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Python SDK for the LetIt API
|
|
5
|
+
Requires-Python: >=3.9
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Dist: requests>=2.32.0
|
|
9
|
+
Dynamic: license-file
|
|
10
|
+
|
|
11
|
+
# LetIt Python
|
|
12
|
+
|
|
13
|
+
The official Python SDK for the [LetIt](https://letit.com) API.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install letit
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Setup
|
|
22
|
+
|
|
23
|
+
Find your API token at [https://letit.com/settings/developer](https://letit.com/settings/developer) after creating an account at [https://letit.com/register](https://letit.com/register).
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from letit import LetIt
|
|
27
|
+
|
|
28
|
+
client = LetIt(api_token="your_api_token_here")
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
### Create a micropost
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from letit.schemas.micropost import PostType
|
|
37
|
+
|
|
38
|
+
# Text post
|
|
39
|
+
post = client.micropost.client_create_micropost(
|
|
40
|
+
title="Hello World",
|
|
41
|
+
body="This is my first post.",
|
|
42
|
+
)
|
|
43
|
+
print(post.public_id)
|
|
44
|
+
print(post.link)
|
|
45
|
+
|
|
46
|
+
# Media post
|
|
47
|
+
with open("photo.png", "rb") as f:
|
|
48
|
+
post = client.micropost.client_create_micropost(
|
|
49
|
+
title="My photo",
|
|
50
|
+
body="Check this out",
|
|
51
|
+
post_type=PostType.MEDIA,
|
|
52
|
+
file=("photo.png", f, "image/png"),
|
|
53
|
+
)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Create a job post
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from letit.schemas.job import JobLocation, JobType, JobCategory, JobExperienceLevel
|
|
60
|
+
|
|
61
|
+
job = client.job.client_create_user_job_with_company(
|
|
62
|
+
company_name="LetIt",
|
|
63
|
+
company_description="We build things.",
|
|
64
|
+
company_website="https://letit.com",
|
|
65
|
+
job_title="Rust Engineer",
|
|
66
|
+
job_description="Build backend services in Rust.",
|
|
67
|
+
job_how_to_apply="https://letit.com/careers",
|
|
68
|
+
job_location=JobLocation.REMOTE,
|
|
69
|
+
job_type=JobType.FULLTIME,
|
|
70
|
+
job_category=JobCategory.PROGRAMMING,
|
|
71
|
+
job_experience_level=JobExperienceLevel.SENIOR,
|
|
72
|
+
job_skills="Rust, SQL",
|
|
73
|
+
)
|
|
74
|
+
print(job.slug)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## API Reference
|
|
78
|
+
|
|
79
|
+
### `LetIt(api_token, base_url?)`
|
|
80
|
+
|
|
81
|
+
| Parameter | Type | Description |
|
|
82
|
+
|-----------|------|-------------|
|
|
83
|
+
| `api_token` | `str` | Your API token |
|
|
84
|
+
| `base_url` | `str` | API base URL (default: `https://api.letit.com`) |
|
|
85
|
+
|
|
86
|
+
### `client.micropost.client_create_micropost(...)`
|
|
87
|
+
|
|
88
|
+
| Parameter | Type | Default | Description |
|
|
89
|
+
|-----------|------|---------|-------------|
|
|
90
|
+
| `body` | `str` | required | Content of the post |
|
|
91
|
+
| `title` | `str` | `None` | Required for original posts |
|
|
92
|
+
| `post_type` | `PostType` | `PostType.TEXT` | `PostType.TEXT` or `PostType.MEDIA` |
|
|
93
|
+
| `community_name` | `str` | `None` | Community to post in |
|
|
94
|
+
| `parent_micropost_public_id` | `str` | `None` | For replies |
|
|
95
|
+
| `parent_micropost_comment_public_id` | `str` | `None` | For nested replies |
|
|
96
|
+
| `allow_comments` | `bool` | `True` | Whether comments are allowed |
|
|
97
|
+
| `is_draft` | `bool` | `False` | Save as draft |
|
|
98
|
+
| `file` | `tuple` | `None` | `(filename, file_object, mime_type)` for MEDIA posts |
|
|
99
|
+
|
|
100
|
+
### `client.job.client_create_user_job_with_company(...)`
|
|
101
|
+
|
|
102
|
+
| Parameter | Type | Default | Description |
|
|
103
|
+
|-----------|------|---------|-------------|
|
|
104
|
+
| `company_name` | `str` | required | Name of the company |
|
|
105
|
+
| `company_description` | `str` | required | Description of the company |
|
|
106
|
+
| `company_website` | `str` | required | Company website URL |
|
|
107
|
+
| `job_title` | `str` | required | Title of the job |
|
|
108
|
+
| `job_description` | `str` | required | Full job description |
|
|
109
|
+
| `job_how_to_apply` | `str` | required | URL or instructions to apply |
|
|
110
|
+
| `company_logo` | `tuple` | `None` | `(filename, file_object, mime_type)` |
|
|
111
|
+
| `company_location` | `str` | `None` | Company location |
|
|
112
|
+
| `job_location` | `JobLocation` | `JobLocation.REMOTE` | `REMOTE`, `ONSITE`, `HYBRID` |
|
|
113
|
+
| `job_type` | `JobType` | `JobType.FULLTIME` | `FULLTIME`, `PARTTIME`, `CONTRACT`, `FREELANCE`, `INTERNSHIP` |
|
|
114
|
+
| `job_category` | `JobCategory` | `JobCategory.PROGRAMMING` | `PROGRAMMING`, `BLOCKCHAIN`, `DESIGN`, `MARKETING`, `CUSTOMERSUPPORT`, `WRITING`, `PRODUCT`, `SERVICE`, `HUMANRESOURCE`, `ELSE` |
|
|
115
|
+
| `job_experience_level` | `JobExperienceLevel` | `JobExperienceLevel.ALL` | `ALL`, `JUNIOR`, `MID`, `SENIOR`, `NOEXPERIENCEREQUIRED` |
|
|
116
|
+
| `job_minimum_salary` | `int` | `None` | Minimum salary |
|
|
117
|
+
| `job_maximum_salary` | `int` | `None` | Maximum salary |
|
|
118
|
+
| `job_pay_in_cryptocurrency` | `bool` | `False` | Pay in cryptocurrency |
|
|
119
|
+
| `job_skills` | `str` | `None` | Comma-separated skills |
|
|
120
|
+
|
|
121
|
+
## Development
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Install in editable mode
|
|
125
|
+
pip install -e .
|
|
126
|
+
|
|
127
|
+
# Run unit tests
|
|
128
|
+
python -m pytest letit/tests/test_letit.py -v
|
|
129
|
+
|
|
130
|
+
# Run integration tests (requires real API token)
|
|
131
|
+
LETIT_API_TOKEN=your_token python -m pytest letit/tests/test_letit_integration.py -v -s
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## License
|
|
135
|
+
|
|
136
|
+
MIT
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
letit/__init__.py
|
|
5
|
+
letit/client.py
|
|
6
|
+
letit/settings.py
|
|
7
|
+
letit.egg-info/PKG-INFO
|
|
8
|
+
letit.egg-info/SOURCES.txt
|
|
9
|
+
letit.egg-info/dependency_links.txt
|
|
10
|
+
letit.egg-info/requires.txt
|
|
11
|
+
letit.egg-info/top_level.txt
|
|
12
|
+
letit/resources/__init__.py
|
|
13
|
+
letit/resources/job.py
|
|
14
|
+
letit/resources/micropost.py
|
|
15
|
+
letit/schemas/__init__.py
|
|
16
|
+
letit/schemas/common.py
|
|
17
|
+
letit/schemas/job.py
|
|
18
|
+
letit/schemas/micropost.py
|
|
19
|
+
letit/tests/test_letit_integration.py
|
|
20
|
+
letit/tests/test_letit_unit.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
requests>=2.32.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
letit
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "letit"
|
|
7
|
+
# version = "0.0.3" # Test
|
|
8
|
+
version = "0.0.1" # Prod
|
|
9
|
+
description = "Python SDK for the LetIt API"
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
|
+
dependencies = [
|
|
13
|
+
# "httpx>=0.27.0"
|
|
14
|
+
"requests>=2.32.0"
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[tool.setuptools.packages.find]
|
|
18
|
+
include = ["letit*"]
|
letit-0.0.1/setup.cfg
ADDED