hh-applicant-tool 0.5.2__py3-none-any.whl → 0.5.4__py3-none-any.whl
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.
Potentially problematic release.
This version of hh-applicant-tool might be problematic. Click here for more details.
- hh_applicant_tool/ai/__init__.py +0 -0
- hh_applicant_tool/ai/blackbox.py +55 -0
- hh_applicant_tool/operations/apply_similar.py +65 -20
- hh_applicant_tool/operations/config.py +36 -0
- hh_applicant_tool/utils.py +2 -2
- {hh_applicant_tool-0.5.2.dist-info → hh_applicant_tool-0.5.4.dist-info}/METADATA +37 -4
- {hh_applicant_tool-0.5.2.dist-info → hh_applicant_tool-0.5.4.dist-info}/RECORD +9 -6
- {hh_applicant_tool-0.5.2.dist-info → hh_applicant_tool-0.5.4.dist-info}/WHEEL +1 -1
- {hh_applicant_tool-0.5.2.dist-info → hh_applicant_tool-0.5.4.dist-info}/entry_points.txt +0 -0
|
File without changes
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from copy import deepcopy
|
|
3
|
+
|
|
4
|
+
import requests
|
|
5
|
+
|
|
6
|
+
logger = logging.getLogger(__package__)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BlackboxError(Exception):
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class BlackboxChat:
|
|
14
|
+
chat_endpoint: str = "https://www.blackbox.ai/api/chat"
|
|
15
|
+
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
session_id: str,
|
|
19
|
+
chat_payload: dict,
|
|
20
|
+
proxies: dict[str, str] = {},
|
|
21
|
+
session: requests.Session | None = None,
|
|
22
|
+
):
|
|
23
|
+
self.session_id = session_id
|
|
24
|
+
self.chat_payload = chat_payload
|
|
25
|
+
self.proxies = proxies
|
|
26
|
+
self.session = session or requests.session()
|
|
27
|
+
|
|
28
|
+
def default_headers(self) -> dict[str, str]:
|
|
29
|
+
return {
|
|
30
|
+
"Accept": "*/*",
|
|
31
|
+
"Accept-Language": "en-US,en;q=0.9,ru;q=0.8",
|
|
32
|
+
"Content-Type": "application/json",
|
|
33
|
+
"Origin": "https://www.blackbox.ai",
|
|
34
|
+
"Priority": "u=0",
|
|
35
|
+
"Referer": "https://www.blackbox.ai/",
|
|
36
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
def send_message(self, message: str) -> str:
|
|
40
|
+
payload = deepcopy(self.chat_payload)
|
|
41
|
+
payload["messages"].append(
|
|
42
|
+
{**payload["messages"][0], "content": message}
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
response = self.session.post(
|
|
47
|
+
self.chat_endpoint,
|
|
48
|
+
json=payload,
|
|
49
|
+
cookies={"sessionId": self.session_id},
|
|
50
|
+
headers=self.default_headers(),
|
|
51
|
+
proxies=self.proxies,
|
|
52
|
+
)
|
|
53
|
+
return response.text
|
|
54
|
+
except requests.exceptions.RequestException as ex:
|
|
55
|
+
raise BlackboxError(str(ex)) from ex
|
|
@@ -6,6 +6,7 @@ from collections import defaultdict
|
|
|
6
6
|
from datetime import datetime, timedelta, timezone
|
|
7
7
|
from typing import TextIO, Tuple
|
|
8
8
|
|
|
9
|
+
from ..ai.blackbox import BlackboxChat, BlackboxError
|
|
9
10
|
from ..api import ApiError, BadRequest
|
|
10
11
|
from ..main import BaseOperation
|
|
11
12
|
from ..main import Namespace as BaseNamespace
|
|
@@ -15,6 +16,7 @@ from ..telemetry_client import TelemetryClient, TelemetryError
|
|
|
15
16
|
from ..types import ApiListResponse, VacancyItem
|
|
16
17
|
from ..utils import (fix_datetime, parse_interval, parse_invalid_datetime,
|
|
17
18
|
random_text, truncate_string)
|
|
19
|
+
from hh_applicant_tool.ai import blackbox
|
|
18
20
|
|
|
19
21
|
logger = logging.getLogger(__package__)
|
|
20
22
|
|
|
@@ -23,8 +25,10 @@ class Namespace(BaseNamespace):
|
|
|
23
25
|
resume_id: str | None
|
|
24
26
|
message_list: TextIO
|
|
25
27
|
force_message: bool
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
use_ai: bool
|
|
29
|
+
pre_prompt: str
|
|
30
|
+
apply_interval: tuple[float, float]
|
|
31
|
+
page_interval: tuple[float, float]
|
|
28
32
|
order_by: str
|
|
29
33
|
search: str
|
|
30
34
|
dry_run: bool
|
|
@@ -36,16 +40,32 @@ class Operation(BaseOperation, GetResumeIdMixin):
|
|
|
36
40
|
def setup_parser(self, parser: argparse.ArgumentParser) -> None:
|
|
37
41
|
parser.add_argument("--resume-id", help="Идентефикатор резюме")
|
|
38
42
|
parser.add_argument(
|
|
43
|
+
"-L",
|
|
39
44
|
"--message-list",
|
|
40
45
|
help="Путь до файла, где хранятся сообщения для отклика на вакансии. Каждое сообщение — с новой строки.",
|
|
41
|
-
type=argparse.FileType(),
|
|
46
|
+
type=argparse.FileType('r', encoding='utf-8', errors='replace'),
|
|
42
47
|
)
|
|
43
48
|
parser.add_argument(
|
|
49
|
+
"-f",
|
|
44
50
|
"--force-message",
|
|
51
|
+
"--force",
|
|
45
52
|
help="Всегда отправлять сообщение при отклике",
|
|
46
53
|
default=False,
|
|
47
54
|
action=argparse.BooleanOptionalAction,
|
|
48
55
|
)
|
|
56
|
+
parser.add_argument(
|
|
57
|
+
"--use-ai",
|
|
58
|
+
"--ai",
|
|
59
|
+
help="Использовать AI для генерации сообщений",
|
|
60
|
+
default=False,
|
|
61
|
+
action=argparse.BooleanOptionalAction,
|
|
62
|
+
)
|
|
63
|
+
parser.add_argument(
|
|
64
|
+
"--pre-prompt",
|
|
65
|
+
"--prompt",
|
|
66
|
+
help="Добавочный промпт для генерации сопроводительного письма",
|
|
67
|
+
default="Сгенерируй сопроводительное письмо не более 5-7 предложений от моего имени для вакансии",
|
|
68
|
+
)
|
|
49
69
|
parser.add_argument(
|
|
50
70
|
"--apply-interval",
|
|
51
71
|
help="Интервал перед отправкой откликов в секундах (X, X-Y)",
|
|
@@ -86,24 +106,35 @@ class Operation(BaseOperation, GetResumeIdMixin):
|
|
|
86
106
|
def run(self, args: Namespace) -> None:
|
|
87
107
|
self.enable_telemetry = True
|
|
88
108
|
if args.disable_telemetry:
|
|
89
|
-
print(
|
|
90
|
-
|
|
91
|
-
)
|
|
92
|
-
if (
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
):
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
else:
|
|
100
|
-
|
|
109
|
+
# print(
|
|
110
|
+
# "👁️ Телеметрия используется только для сбора данных о работодателях и их вакансиях, персональные данные пользователей не передаются на сервер."
|
|
111
|
+
# )
|
|
112
|
+
# if (
|
|
113
|
+
# input("Вы действительно хотите отключить телеметрию (д/Н)? ")
|
|
114
|
+
# .lower()
|
|
115
|
+
# .startswith(("д", "y"))
|
|
116
|
+
# ):
|
|
117
|
+
# self.enable_telemetry = False
|
|
118
|
+
# logger.info("Телеметрия отключена.")
|
|
119
|
+
# else:
|
|
120
|
+
# logger.info("Спасибо за то что оставили телеметрию включенной!")
|
|
121
|
+
self.enable_telemetry = False
|
|
101
122
|
|
|
102
123
|
self.api = get_api(args)
|
|
103
124
|
self.resume_id = args.resume_id or self._get_resume_id()
|
|
104
125
|
self.application_messages = self._get_application_messages(
|
|
105
126
|
args.message_list
|
|
106
127
|
)
|
|
128
|
+
self.chat = None
|
|
129
|
+
|
|
130
|
+
if config := args.config.get("blackbox"):
|
|
131
|
+
self.chat = BlackboxChat(
|
|
132
|
+
session_id=config["session_id"],
|
|
133
|
+
chat_payload=config["chat_payload"],
|
|
134
|
+
proxies=self.api.proxies or {},
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
self.pre_prompt = args.pre_prompt
|
|
107
138
|
|
|
108
139
|
self.apply_min_interval, self.apply_max_interval = args.apply_interval
|
|
109
140
|
self.page_min_interval, self.page_max_interval = args.page_interval
|
|
@@ -255,7 +286,7 @@ class Operation(BaseOperation, GetResumeIdMixin):
|
|
|
255
286
|
|
|
256
287
|
if not do_apply:
|
|
257
288
|
logger.debug(
|
|
258
|
-
"
|
|
289
|
+
"Пропускаем вакансию так как достигла лимита заявок: %s",
|
|
259
290
|
vacancy["alternate_url"],
|
|
260
291
|
)
|
|
261
292
|
continue
|
|
@@ -276,11 +307,25 @@ class Operation(BaseOperation, GetResumeIdMixin):
|
|
|
276
307
|
if self.force_message or vacancy.get(
|
|
277
308
|
"response_letter_required"
|
|
278
309
|
):
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
310
|
+
if self.chat:
|
|
311
|
+
try:
|
|
312
|
+
msg = self.pre_prompt + "\n\n"
|
|
313
|
+
msg += message_placeholders["vacancy_name"]
|
|
314
|
+
logger.debug(msg)
|
|
315
|
+
msg = self.chat.send_message(msg)
|
|
316
|
+
except BlackboxError as ex:
|
|
317
|
+
logger.error(ex)
|
|
318
|
+
continue
|
|
319
|
+
else:
|
|
320
|
+
msg = (
|
|
321
|
+
random_text(
|
|
322
|
+
random.choice(self.application_messages)
|
|
323
|
+
)
|
|
324
|
+
% message_placeholders
|
|
325
|
+
)
|
|
326
|
+
|
|
283
327
|
logger.debug(msg)
|
|
328
|
+
params["message"] = msg
|
|
284
329
|
|
|
285
330
|
if self.dry_run:
|
|
286
331
|
logger.info(
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
import subprocess
|
|
5
|
+
|
|
6
|
+
from ..main import BaseOperation
|
|
7
|
+
from ..main import Namespace as BaseNamespace
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__package__)
|
|
10
|
+
|
|
11
|
+
EDITOR = os.getenv("EDITOR", "nano")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Namespace(BaseNamespace):
|
|
15
|
+
print: bool
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Operation(BaseOperation):
|
|
19
|
+
"""Редактировать конфигурационный файл или показать путь до него"""
|
|
20
|
+
|
|
21
|
+
def setup_parser(self, parser: argparse.ArgumentParser) -> None:
|
|
22
|
+
parser.add_argument(
|
|
23
|
+
"-p",
|
|
24
|
+
"--print",
|
|
25
|
+
type=bool,
|
|
26
|
+
default=False,
|
|
27
|
+
action=argparse.BooleanOptionalAction,
|
|
28
|
+
help="Напечатать путь и выйти",
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
def run(self, args: Namespace) -> None:
|
|
32
|
+
config_path = str(args.config._config_path)
|
|
33
|
+
if args.print:
|
|
34
|
+
print(config_path)
|
|
35
|
+
else:
|
|
36
|
+
subprocess.call([EDITOR, config_path])
|
hh_applicant_tool/utils.py
CHANGED
|
@@ -44,7 +44,7 @@ class Config(dict):
|
|
|
44
44
|
def load(self) -> None:
|
|
45
45
|
if self._config_path.exists():
|
|
46
46
|
with self._lock:
|
|
47
|
-
with self._config_path.open() as f:
|
|
47
|
+
with self._config_path.open("r", encoding="utf-8", errors="replace") as f:
|
|
48
48
|
try:
|
|
49
49
|
self.update(json.load(f))
|
|
50
50
|
except ValueError:
|
|
@@ -54,7 +54,7 @@ class Config(dict):
|
|
|
54
54
|
self.update(*args, **kwargs)
|
|
55
55
|
self._config_path.parent.mkdir(exist_ok=True, parents=True)
|
|
56
56
|
with self._lock:
|
|
57
|
-
with self._config_path.open("w+") as fp:
|
|
57
|
+
with self._config_path.open("w+", encoding="utf-8", errors="replace") as fp:
|
|
58
58
|
json.dump(
|
|
59
59
|
self,
|
|
60
60
|
fp,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: hh-applicant-tool
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.4
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Senior YAML Developer
|
|
6
6
|
Author-email: yamldeveloper@proton.me
|
|
@@ -32,7 +32,9 @@ Description-Content-Type: text/markdown
|
|
|
32
32
|
|
|
33
33
|
### Описание
|
|
34
34
|
|
|
35
|
-
Утилита для
|
|
35
|
+
> Утилита для генерации сопроводительного письма может использовать AI
|
|
36
|
+
|
|
37
|
+
Утилита для успешных волчат и старых волков с опытом, служащая для автоматизации действий на HH.RU таких как рассылка откликов на подходящие вакансии и обновление всех резюме (бесплатный аналог услуги на HH). Но данная утилита больше чем просто спамилка откликами, вы так же выступаете в роли тайного агента, и если в списке подходящих вакансий встречается отказ, она возвращает ссылку на обсуждение работодателя в группе [Отзывы о работодателях с HH.RU](https://t.me/otzyvy_headhunter). Там вы можете написать отзыв о работодателе и почитать чужие. Для этого собираются данные о работодателях и их вакансиях (персональные данные пользователя не передаются ни в каком виде). Отправку данных на сервер разработчика можно отключить, но тогда вы не получите ссылку на обсуждение, а так же не сможете пожаловаться на неадекватного мудака, выкатившего отказ после "небольшого" тестового задания на недельку. Через сайты на таких жаловаться бесполезно: владелец сайта за деньги или после угроз судом удаляют отзывы. Единственное место где можно написать отзыв — это **Telegram**.
|
|
36
38
|
|
|
37
39
|
Работает с Python >= 3.10. Нужную версию Python можно поставить через
|
|
38
40
|
asdf/pyenv/conda и что-то еще.
|
|
@@ -166,6 +168,11 @@ $ hh-applicant-tool refresh-token
|
|
|
166
168
|
| **macOS** | `~/Library/Application Support/hh-applicant-tool/config.json` |
|
|
167
169
|
| **Linux** | `~/.config/hh-applicant-tool/config.json` |
|
|
168
170
|
|
|
171
|
+
Полный путь до конфигурационного файла можно вывести с помощью команды:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
hh-applicant-tool config -p
|
|
175
|
+
```
|
|
169
176
|
|
|
170
177
|
Через конфиг можно задать дополнительные настройки:
|
|
171
178
|
|
|
@@ -238,11 +245,12 @@ https://hh.ru/employer/1918903
|
|
|
238
245
|
| **whoami** | Выводит информацию об авторизованном пользователе |
|
|
239
246
|
| **list-resumes** | Список резюме |
|
|
240
247
|
| **update-resumes** | Обновить все резюме. Аналогично нажатию кнопки «Обновить дату». |
|
|
241
|
-
| **apply-similar** | Откликнуться на все подходящие вакансии. Лимит = 200 в день. На HH есть спам-фильтры, так что лучше не рассылайте отклики со
|
|
248
|
+
| **apply-similar** | Откликнуться на все подходящие вакансии. Лимит = 200 в день. На HH есть спам-фильтры, так что лучше не рассылайте отклики со ссылками, иначе рискуете попасть в теневой бан. |
|
|
242
249
|
| **reply-employers** | Ответить во все чаты с работодателями, где нет ответа либо не прочитали ваш предыдущий ответ |
|
|
243
250
|
| **clear-negotiations** | Удаляет отказы и отменяет заявки, которые долго висят |
|
|
244
251
|
| **call-api** | Вызов произвольного метода API с выводом результата. |
|
|
245
252
|
| **refresh-token** | Обновляет access_token. |
|
|
253
|
+
| **config** | Редактировать конфигурационный файл. |
|
|
246
254
|
| **get-employer-contacts** | Получить список контактов работодателя, даже если тот не высылал приглашения. Это функционал для избранных, но в группе есть бесплатный бот с тем же функционалом. |
|
|
247
255
|
|
|
248
256
|
### Формат текста сообщений
|
|
@@ -276,6 +284,31 @@ https://hh.ru/employer/1918903
|
|
|
276
284
|
Привет, как ты?
|
|
277
285
|
```
|
|
278
286
|
|
|
287
|
+
### Использование AI для генерации сопроводительного письма
|
|
288
|
+
|
|
289
|
+
* Перейдите на сайт [blackbox.ai](https://www.blackbox.ai) и создайте чат.
|
|
290
|
+
* В первом сообщении опишите свой опыт и тп.
|
|
291
|
+
* Далее откройте devtools, нажав `F12`.
|
|
292
|
+
* Во вкладке `Network` последним должен быть POST-запрос на `https://www.blackbox.ai/api/chat`.
|
|
293
|
+
* Запустите редактирование конфига:
|
|
294
|
+
```sh
|
|
295
|
+
hh-applicant-tool config
|
|
296
|
+
```
|
|
297
|
+
* Измените конфиг:
|
|
298
|
+
```json
|
|
299
|
+
{
|
|
300
|
+
// ...
|
|
301
|
+
"blackbox": {
|
|
302
|
+
"session_id": "<В заголовках запроса найдите Cookie, скопируйте сюда значение sessionId до ;>",
|
|
303
|
+
"chat_payload": <Сюда вставьте тело запроса типа {"messages":[{"id":"IXqdOx9","content":"Я программист fullstack-разработчик...","role":"user"}],"id":"IXqdOx9","previewToken":null,"userId":null,...,"webSearchModePrompt":false,"deepSearchMode":false}>
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
* Пример рассылки откликов с генерированным письмом:
|
|
308
|
+
```sh
|
|
309
|
+
hh-applicant-tool apply-similar -f --ai
|
|
310
|
+
```
|
|
311
|
+
|
|
279
312
|
### Написание плагинов
|
|
280
313
|
|
|
281
314
|
Утилита использует систему плагинов. Все они лежат в [operations](https://github.com/s3rgeym/hh-applicant-tool/tree/main/hh_applicant_tool/operations). Модули расположенные там автоматически добавляются как доступные операции. За основу для своего плагина можно взять [whoami.py](https://github.com/s3rgeym/hh-applicant-tool/tree/main/hh_applicant_tool/operations/whoami.py).
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
hh_applicant_tool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
hh_applicant_tool/__main__.py,sha256=cwKJAAML0RRKT9Qbzcwf07HHcuSd8oh7kx4P1apndWQ,84
|
|
3
|
+
hh_applicant_tool/ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
hh_applicant_tool/ai/blackbox.py,sha256=vqkEpsX7q7bgX49dmmifYJmrbuz_WBg5u9M9J9XdQlI,1670
|
|
3
5
|
hh_applicant_tool/api/__init__.py,sha256=kgFSHibRaAugN2BA3U1djEa20qgKJUUVouwJzjEB0DU,84
|
|
4
6
|
hh_applicant_tool/api/client.py,sha256=um9NX22hNOtSuPCobCKf1anIFp-jiZlIXm4BuqN-L7k,7997
|
|
5
7
|
hh_applicant_tool/api/errors.py,sha256=0SoWKnsSUA0K2YgQA8GwGhe-pRMwtfK94MR6_MgbORQ,1722
|
|
@@ -8,10 +10,11 @@ hh_applicant_tool/constants.py,sha256=lpgKkP2chWgTnBXvzxbSPWpKcfzp8VxMTlkssFcQhH
|
|
|
8
10
|
hh_applicant_tool/main.py,sha256=z_SAW7cV83P5mVEkuddSzETUGLqocsNyEKlA6HBHjQ0,4806
|
|
9
11
|
hh_applicant_tool/mixins.py,sha256=66LmyYSsDfhrpUwoAONjzrd5aoXqaZVoQ-zXhyYbYMk,418
|
|
10
12
|
hh_applicant_tool/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
-
hh_applicant_tool/operations/apply_similar.py,sha256=
|
|
13
|
+
hh_applicant_tool/operations/apply_similar.py,sha256=IYpf8PabOJF6vmbsKYir1NgW0Y2XviBanIGjsbz9AD4,16649
|
|
12
14
|
hh_applicant_tool/operations/authorize.py,sha256=TyUTCSOGwSYVJMEd5vSI981LRRI-RZf8hnlVYhtRVwA,3184
|
|
13
15
|
hh_applicant_tool/operations/call_api.py,sha256=qwPDrWP9tiqHkaYYWYBZtymj9AaxObB86Eny-Bf5q_c,1314
|
|
14
16
|
hh_applicant_tool/operations/clear_negotiations.py,sha256=GEsL1snxz8TJ3i7Nz6LkP4FZOzRBdAofX3xf3Ywj64k,4369
|
|
17
|
+
hh_applicant_tool/operations/config.py,sha256=PJpPPDJaQwqyZ_T55Mlf0oAoeNeMUG_yJoz605XZGxI,959
|
|
15
18
|
hh_applicant_tool/operations/get_employer_contacts.py,sha256=7BEzEnNAp87RlOP6HX0LR6cbtud2FuKCKK5sq6fINq8,4066
|
|
16
19
|
hh_applicant_tool/operations/list_resumes.py,sha256=XBrVFTnl45BUtuvjVm70h_CXZrOvAULnLkLkyUh7gxw,1134
|
|
17
20
|
hh_applicant_tool/operations/refresh_token.py,sha256=hYTmzBzJFSsb-LDO2_w0Y30WVWsctIH7vTzirkLwzWo,1267
|
|
@@ -20,8 +23,8 @@ hh_applicant_tool/operations/update_resumes.py,sha256=gGxMYMoT9GqJjwn4AgrOAEJCZu
|
|
|
20
23
|
hh_applicant_tool/operations/whoami.py,sha256=sg0r7m6oKkpMEmGt4QdtYdS-1gf-1KKdnk32yblbRJs,714
|
|
21
24
|
hh_applicant_tool/telemetry_client.py,sha256=wYLbKnx3sOmESFHqjLt-0Gww1O3lJiXFYdWnsorIhK8,3261
|
|
22
25
|
hh_applicant_tool/types.py,sha256=q3yaIcq-UOkPzjxws0OFa4w9fTty-yx79_dic70_dUM,843
|
|
23
|
-
hh_applicant_tool/utils.py,sha256=
|
|
24
|
-
hh_applicant_tool-0.5.
|
|
25
|
-
hh_applicant_tool-0.5.
|
|
26
|
-
hh_applicant_tool-0.5.
|
|
27
|
-
hh_applicant_tool-0.5.
|
|
26
|
+
hh_applicant_tool/utils.py,sha256=pKmyG55HGmOvOXtHK0x9JBdEfm-hd1b8XroG9tEPSPQ,3146
|
|
27
|
+
hh_applicant_tool-0.5.4.dist-info/METADATA,sha256=d8j1CSX0o5ezl2xq1J-jd5T-ckWLgsgMAd9W2aD8oGM,20687
|
|
28
|
+
hh_applicant_tool-0.5.4.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
|
29
|
+
hh_applicant_tool-0.5.4.dist-info/entry_points.txt,sha256=Vb7M2YaYLMtKYJZh8chIrXZApMzSRFT1-rQw-U9r10g,65
|
|
30
|
+
hh_applicant_tool-0.5.4.dist-info/RECORD,,
|
|
File without changes
|