hh-applicant-tool 0.7.10__py3-none-any.whl → 1.4.12__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.
- hh_applicant_tool/__init__.py +1 -0
- hh_applicant_tool/__main__.py +1 -1
- hh_applicant_tool/ai/base.py +2 -0
- hh_applicant_tool/ai/openai.py +25 -35
- hh_applicant_tool/api/__init__.py +4 -2
- hh_applicant_tool/api/client.py +65 -68
- hh_applicant_tool/{constants.py → api/client_keys.py} +3 -6
- hh_applicant_tool/api/datatypes.py +293 -0
- hh_applicant_tool/api/errors.py +57 -7
- hh_applicant_tool/api/user_agent.py +17 -0
- hh_applicant_tool/main.py +234 -113
- hh_applicant_tool/operations/apply_similar.py +353 -371
- hh_applicant_tool/operations/authorize.py +313 -120
- hh_applicant_tool/operations/call_api.py +18 -8
- hh_applicant_tool/operations/check_proxy.py +30 -0
- hh_applicant_tool/operations/clear_negotiations.py +90 -82
- hh_applicant_tool/operations/config.py +119 -16
- hh_applicant_tool/operations/install.py +34 -0
- hh_applicant_tool/operations/list_resumes.py +23 -11
- hh_applicant_tool/operations/log.py +77 -0
- hh_applicant_tool/operations/migrate_db.py +65 -0
- hh_applicant_tool/operations/query.py +122 -0
- hh_applicant_tool/operations/refresh_token.py +14 -13
- hh_applicant_tool/operations/reply_employers.py +201 -180
- hh_applicant_tool/operations/settings.py +95 -0
- hh_applicant_tool/operations/uninstall.py +26 -0
- hh_applicant_tool/operations/update_resumes.py +23 -11
- hh_applicant_tool/operations/whoami.py +40 -7
- hh_applicant_tool/storage/__init__.py +8 -0
- hh_applicant_tool/storage/facade.py +24 -0
- hh_applicant_tool/storage/models/__init__.py +0 -0
- hh_applicant_tool/storage/models/base.py +169 -0
- hh_applicant_tool/storage/models/contacts.py +28 -0
- hh_applicant_tool/storage/models/employer.py +12 -0
- hh_applicant_tool/storage/models/negotiation.py +16 -0
- hh_applicant_tool/storage/models/resume.py +19 -0
- hh_applicant_tool/storage/models/setting.py +6 -0
- hh_applicant_tool/storage/models/vacancy.py +36 -0
- hh_applicant_tool/storage/queries/migrations/.gitkeep +0 -0
- hh_applicant_tool/storage/queries/schema.sql +132 -0
- hh_applicant_tool/storage/repositories/__init__.py +0 -0
- hh_applicant_tool/storage/repositories/base.py +230 -0
- hh_applicant_tool/storage/repositories/contacts.py +14 -0
- hh_applicant_tool/storage/repositories/employers.py +14 -0
- hh_applicant_tool/storage/repositories/errors.py +19 -0
- hh_applicant_tool/storage/repositories/negotiations.py +13 -0
- hh_applicant_tool/storage/repositories/resumes.py +9 -0
- hh_applicant_tool/storage/repositories/settings.py +35 -0
- hh_applicant_tool/storage/repositories/vacancies.py +9 -0
- hh_applicant_tool/storage/utils.py +40 -0
- hh_applicant_tool/utils/__init__.py +31 -0
- hh_applicant_tool/utils/attrdict.py +6 -0
- hh_applicant_tool/utils/binpack.py +167 -0
- hh_applicant_tool/utils/config.py +55 -0
- hh_applicant_tool/utils/date.py +19 -0
- hh_applicant_tool/utils/json.py +61 -0
- hh_applicant_tool/{jsonc.py → utils/jsonc.py} +12 -6
- hh_applicant_tool/utils/log.py +147 -0
- hh_applicant_tool/utils/misc.py +12 -0
- hh_applicant_tool/utils/mixins.py +221 -0
- hh_applicant_tool/utils/string.py +27 -0
- hh_applicant_tool/utils/terminal.py +32 -0
- hh_applicant_tool-1.4.12.dist-info/METADATA +685 -0
- hh_applicant_tool-1.4.12.dist-info/RECORD +68 -0
- hh_applicant_tool/ai/blackbox.py +0 -55
- hh_applicant_tool/color_log.py +0 -47
- hh_applicant_tool/mixins.py +0 -13
- hh_applicant_tool/operations/delete_telemetry.py +0 -30
- hh_applicant_tool/operations/get_employer_contacts.py +0 -348
- hh_applicant_tool/telemetry_client.py +0 -106
- hh_applicant_tool/types.py +0 -45
- hh_applicant_tool/utils.py +0 -119
- hh_applicant_tool-0.7.10.dist-info/METADATA +0 -452
- hh_applicant_tool-0.7.10.dist-info/RECORD +0 -33
- {hh_applicant_tool-0.7.10.dist-info → hh_applicant_tool-1.4.12.dist-info}/WHEEL +0 -0
- {hh_applicant_tool-0.7.10.dist-info → hh_applicant_tool-1.4.12.dist-info}/entry_points.txt +0 -0
hh_applicant_tool/types.py
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
from typing import TypedDict, Literal
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class AccessToken(TypedDict):
|
|
5
|
-
access_token: str
|
|
6
|
-
refresh_token: str
|
|
7
|
-
expires_in: int
|
|
8
|
-
token_type: Literal["bearer"]
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class ApiListResponse(TypedDict):
|
|
12
|
-
...
|
|
13
|
-
items: list
|
|
14
|
-
found: int
|
|
15
|
-
page: int
|
|
16
|
-
pages: int
|
|
17
|
-
per_page: int
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class VacancyItem(TypedDict):
|
|
21
|
-
accept_incomplete_resumes: bool
|
|
22
|
-
address: dict
|
|
23
|
-
alternate_url: str
|
|
24
|
-
apply_alternate_url: str
|
|
25
|
-
area: dict
|
|
26
|
-
contacts: dict
|
|
27
|
-
counters: dict
|
|
28
|
-
department: dict
|
|
29
|
-
employer: dict
|
|
30
|
-
has_test: bool
|
|
31
|
-
id: int
|
|
32
|
-
insider_interview: dict
|
|
33
|
-
name: str
|
|
34
|
-
professional_roles: list
|
|
35
|
-
published_at: str
|
|
36
|
-
relations: list
|
|
37
|
-
response_letter_required: bool
|
|
38
|
-
response_url: str | None
|
|
39
|
-
salary: dict
|
|
40
|
-
schedule: dict
|
|
41
|
-
snippet: dict
|
|
42
|
-
sort_point_distance: float
|
|
43
|
-
type: dict
|
|
44
|
-
url: str
|
|
45
|
-
experience: dict
|
hh_applicant_tool/utils.py
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import hashlib
|
|
4
|
-
import json
|
|
5
|
-
import platform
|
|
6
|
-
import random
|
|
7
|
-
import re
|
|
8
|
-
import sys
|
|
9
|
-
import uuid
|
|
10
|
-
from datetime import datetime
|
|
11
|
-
from functools import partial
|
|
12
|
-
from os import getenv
|
|
13
|
-
from pathlib import Path
|
|
14
|
-
from threading import Lock
|
|
15
|
-
from typing import Any
|
|
16
|
-
|
|
17
|
-
from .constants import INVALID_ISO8601_FORMAT
|
|
18
|
-
|
|
19
|
-
print_err = partial(print, file=sys.stderr, flush=True)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def get_config_path() -> Path:
|
|
23
|
-
match platform.system():
|
|
24
|
-
case "Windows":
|
|
25
|
-
return Path(getenv("APPDATA", Path.home() / "AppData" / "Roaming"))
|
|
26
|
-
case "Darwin": # macOS
|
|
27
|
-
return Path.home() / "Library" / "Application Support"
|
|
28
|
-
case _: # Linux and etc
|
|
29
|
-
return Path(getenv("XDG_CONFIG_HOME", Path.home() / ".config"))
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class AttrDict(dict):
|
|
33
|
-
__getattr__ = dict.get
|
|
34
|
-
__setattr__ = dict.__setitem__
|
|
35
|
-
__delattr__ = dict.__delitem__
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
# TODO: добавить defaults
|
|
39
|
-
class Config(dict):
|
|
40
|
-
def __init__(self, config_path: str | Path | None = None):
|
|
41
|
-
self._config_path = Path(config_path or get_config_path())
|
|
42
|
-
self._lock = Lock()
|
|
43
|
-
self.load()
|
|
44
|
-
|
|
45
|
-
def load(self) -> None:
|
|
46
|
-
if self._config_path.exists():
|
|
47
|
-
with self._lock:
|
|
48
|
-
with self._config_path.open(
|
|
49
|
-
"r", encoding="utf-8", errors="replace"
|
|
50
|
-
) as f:
|
|
51
|
-
self.update(json.load(f))
|
|
52
|
-
|
|
53
|
-
def save(self, *args: Any, **kwargs: Any) -> None:
|
|
54
|
-
self.update(*args, **kwargs)
|
|
55
|
-
self._config_path.parent.mkdir(exist_ok=True, parents=True)
|
|
56
|
-
with self._lock:
|
|
57
|
-
with self._config_path.open("w+", encoding="utf-8", errors="replace") as fp:
|
|
58
|
-
json.dump(
|
|
59
|
-
self,
|
|
60
|
-
fp,
|
|
61
|
-
ensure_ascii=True,
|
|
62
|
-
indent=2,
|
|
63
|
-
sort_keys=True,
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
__getitem__ = dict.get
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def truncate_string(s: str, limit: int = 75, ellipsis: str = "…") -> str:
|
|
70
|
-
return s[:limit] + bool(s[limit:]) * ellipsis
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def make_hash(data: str) -> str:
|
|
74
|
-
# Вычисляем хеш SHA-256
|
|
75
|
-
return hashlib.sha256(data.encode()).hexdigest()
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def parse_invalid_datetime(dt: str) -> datetime:
|
|
79
|
-
return datetime.strptime(dt, INVALID_ISO8601_FORMAT)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def fix_datetime(dt: str | None) -> str | None:
|
|
83
|
-
return parse_invalid_datetime(dt).isoformat() if dt is not None else None
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
def random_text(s: str) -> str:
|
|
87
|
-
while (
|
|
88
|
-
temp := re.sub(
|
|
89
|
-
r"{([^{}]+)}",
|
|
90
|
-
lambda m: random.choice(
|
|
91
|
-
m.group(1).split("|"),
|
|
92
|
-
),
|
|
93
|
-
s,
|
|
94
|
-
)
|
|
95
|
-
) != s:
|
|
96
|
-
s = temp
|
|
97
|
-
return s
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
def parse_interval(interval: str) -> tuple[float, float]:
|
|
101
|
-
"""Парсит строку интервала и возвращает кортеж с минимальным и максимальным значениями."""
|
|
102
|
-
if "-" in interval:
|
|
103
|
-
min_interval, max_interval = map(float, interval.split("-"))
|
|
104
|
-
else:
|
|
105
|
-
min_interval = max_interval = float(interval)
|
|
106
|
-
return min(min_interval, max_interval), max(min_interval, max_interval)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
def android_user_agent() -> str:
|
|
110
|
-
"""Android Default"""
|
|
111
|
-
devices = "23053RN02A, 23053RN02Y, 23053RN02I, 23053RN02L, 23077RABDC".split(", ")
|
|
112
|
-
device = random.choice(devices)
|
|
113
|
-
minor = random.randint(100, 150)
|
|
114
|
-
patch = random.randint(10000, 15000)
|
|
115
|
-
android = random.randint(11, 15)
|
|
116
|
-
return (
|
|
117
|
-
f"ru.hh.android/7.{minor}.{patch}, Device: {device}, "
|
|
118
|
-
f"Android OS: {android} (UUID: {uuid.uuid4()})"
|
|
119
|
-
)
|
|
@@ -1,452 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: hh-applicant-tool
|
|
3
|
-
Version: 0.7.10
|
|
4
|
-
Summary: HH-Applicant-Tool: An automation utility for HeadHunter (hh.ru) designed to streamline the job search process by auto-applying to relevant vacancies and periodically refreshing resumes to stay at the top of recruiter searches.
|
|
5
|
-
Author: Senior YAML Developer
|
|
6
|
-
Author-email: yamldeveloper@proton.me
|
|
7
|
-
Requires-Python: >=3.10,<4.0
|
|
8
|
-
Classifier: Programming Language :: Python :: 3
|
|
9
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
14
|
-
Provides-Extra: qt
|
|
15
|
-
Requires-Dist: prettytable (>=3.6.0,<4.0.0)
|
|
16
|
-
Requires-Dist: pyqt6 (==6.7.0) ; extra == "qt"
|
|
17
|
-
Requires-Dist: pyqt6-webengine (==6.7.0) ; extra == "qt"
|
|
18
|
-
Requires-Dist: requests[socks] (>=2.32.3,<3.0.0)
|
|
19
|
-
Project-URL: Homepage, https://github.com/s3rgeym/hh-applicant-tool
|
|
20
|
-
Project-URL: Repository, https://github.com/s3rgeym/hh-applicant-tool
|
|
21
|
-
Description-Content-Type: text/markdown
|
|
22
|
-
|
|
23
|
-
## HH Applicant Tool
|
|
24
|
-
|
|
25
|
-

|
|
26
|
-
[]()
|
|
27
|
-
[]()
|
|
28
|
-
[]()
|
|
29
|
-
[]()
|
|
30
|
-
[]()
|
|
31
|
-
|
|
32
|
-
<div align="center">
|
|
33
|
-
<img src="https://github.com/user-attachments/assets/29d91490-2c83-4e3f-a573-c7a6182a4044" width="500">
|
|
34
|
-
</div>
|
|
35
|
-
|
|
36
|
-
### Содержание
|
|
37
|
-
|
|
38
|
-
* [🚀 Описание](#описание)
|
|
39
|
-
* [⚠️ Внимание](#внимание)
|
|
40
|
-
* [📜 Предыстория](#предыстория)
|
|
41
|
-
* [📦 Установка](#установка)
|
|
42
|
-
* [🔑 Авторизация](#авторизация)
|
|
43
|
-
* [⚙️ Конфигурация](#пути-до-файла-configjson)
|
|
44
|
-
* [🛠 Описание команд](#описание-команд)
|
|
45
|
-
* [📝 Формат сообщений](#формат-текста-сообщений)
|
|
46
|
-
* [🤖 Использование AI (ChatGPT)](#использование-ai-для-генерации-сопроводительного-письма)
|
|
47
|
-
* [📡 Работа с API напрямую](#работа-с-api-напрямую)
|
|
48
|
-
* [🔌 Добавление своих команд](#добавление-своих-команд)
|
|
49
|
-
|
|
50
|
-
---
|
|
51
|
-
|
|
52
|
-
### Описание
|
|
53
|
-
|
|
54
|
-
> Данной утилите похуй на "запрет" доступа к API HH сторонним приложениям, так как она прикидывается официальным приложением под Android
|
|
55
|
-
|
|
56
|
-
> Утилита для генерации сопроводительного письма может использовать AI в тч ChatGPT. Подробное описание ниже
|
|
57
|
-
|
|
58
|
-
Утилита для успешных волчат и старых волков с опытом, служащая для автоматизации действий на HH.RU таких как рассылка откликов на подходящие вакансии и обновление всех резюме (бесплатный аналог услуги на HH). Утилита сохраняет контактные данные, всех кто вам писал, и позволяет вам по ним проводить поиск (название компании, сайт и тп). Это удобно, так как контакт сохранится даже, если вышлют отказ в дальнейшем. Огромной проблемой являются мошенники на Ха-Ха, притворяющиеся раб-о-тодателями. Так как утилитой пользуются сотни людей, делящихся информацией о работодателях, то очень легко вычислить, что менеджеры работодателей постоянно меняют телефонные номера (вы видите номера только тех, кто вас пригласил). В России в рамках борьбы с нежелательными звонками, номера с которых по 20-30 раз в день звонят тем, кого нет в контактах, блокируют. Поэтому мошенники каждые 2-3 дня изменяют номер телефона в настройках на сайте. Иногда блокируются и номера овчарок, но в таких случаях идет речь о разного рода аутсорсерах/интеграторах, которые перепродают вас с наценкой 200-300-500%, которая вся достается какому-то успешному кабанчику, они ничем в принципе не отличаясь от жуликов. Утилита такие контакты помечает как мошеннические, чтобы вы не тратили время на заполнение анкет, написание сообщений или звонки ублюдкам (ниже есть пример блокировки мошенников). Мой совет: скрывайте свой номер от работодателя, если рассылаете отклики через утилиту, а то количество жуликов на красном сайте мягко говоря зашкаливает. У утилиты есть канал в пашкограме: [HH Applicant Tool](https://t.me/hh_applicant_tool). Старый <s>[HH Resume Automate](https://t.me/hh_resume_automate)</s> был выпилен какими-то долбоебами, углядевшими во флаге Японии с двумя буквами h нарушение авторских прав...
|
|
59
|
-
|
|
60
|
-
<img width="1024" height="1024" alt="image" src="https://github.com/user-attachments/assets/c17e17db-f5d1-4215-bc62-32b0581e8357" />
|
|
61
|
-
|
|
62
|
-
> Утилита предупреждает о подозрительных работодателях, с высокой вероятностью являющихся мошенниками
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
Работает с Python >= 3.10. Нужную версию Python можно поставить через
|
|
66
|
-
asdf/pyenv/conda и что-то еще. В школотронской Manjaro и даже в последних Ubuntu
|
|
67
|
-
версия Python новее.
|
|
68
|
-
|
|
69
|
-
Данная утилита написана для Linux, но будет работать и на Ga..Mac OS, и в Windows, но с WSL не будет, так как для авторизации требуются оконный сервер X11 либо Wayland — только прямая установка пакета через pip в Windows. После авторизации вы можете перенести конфиг на сервер и запускать утилиту через systemd или cron. Столь странный процесс связан с тем, что на странице авторизации запускается море скриптов, которые шифруют данные на клиенте перед отправкой на сервер, а так же выполняется куча запросов чтобы проверить не бот ли ты. Хорошо, что после авторизации никаких проверок по факту нет, даже айпи не проверяется на соответсвие тому с какого была авторизация. В этой лапше мне лень разбираться. Так же при наличии рутованного телефона можно вытащить `access` и `refresh` токены из официального приложения и добавить их в конфиг.
|
|
70
|
-
|
|
71
|
-
Пример работы:
|
|
72
|
-
|
|
73
|
-

|
|
74
|
-
|
|
75
|
-
> Если в веб-интерфейсе выставить фильтры, то они будут применяться в скрипте при отклике на подходящие
|
|
76
|
-
|
|
77
|
-
> Утилита автоматически подхватывает прокси из переменных окружения типа http_proxy или HTTPS_PROXY
|
|
78
|
-
|
|
79
|
-
### Внимание!!!
|
|
80
|
-
|
|
81
|
-
Если для Вас проблема установить данную утилиту, лень разбираться с ее настройкой, то Вы можете установить мое приложение под **Android** [HH Resume Automate](https://github.com/s3rgeym/hh-resume-automate/). Оно обладает минимальным функционалом: обновление резюме (одного) и рассылка откликов (чистить их и тп нельзя).
|
|
82
|
-
|
|
83
|
-
### Предыстория
|
|
84
|
-
|
|
85
|
-
Долгое время я делал массовые заявки с помощью консоли браузера:
|
|
86
|
-
|
|
87
|
-
```js
|
|
88
|
-
$$('[data-qa="vacancy-serp__vacancy_response"]').forEach((el) => el.click());
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
Оно работает, хоть и не идеально. Я даже пробовал автоматизировать рассылки через `p[yu]ppeeter`, пока не прочитал [документацию](https://github.com/hhru/api). И не обнаружил, что **API** (интерфейс) содержит все необходимые мне методы. Headhunter позволяет создать свое приложение, но там ручная модерация, и наврядли кто-то разрешит мне создать приложение для спама заявками. Я [декомпилировал](https://gist.github.com/s3rgeym/eee96bbf91b04f7eb46b7449f8884a00) официальное приложение для **Android** и получил **CLIENT_ID** и **CLIENT_SECRET**, необходимые для работы через **API**.
|
|
92
|
-
|
|
93
|
-
### Установка
|
|
94
|
-
|
|
95
|
-
Универсальный с использованием pipx (требует пакета `python-pipx` в Arch):
|
|
96
|
-
|
|
97
|
-
```bash
|
|
98
|
-
# Версия с поддержкой авторизации через запуск окна с браузером (эта версия очень много весит)
|
|
99
|
-
# Можно использовать обычный pip
|
|
100
|
-
$ pipx install 'hh-applicant-tool[qt]'
|
|
101
|
-
|
|
102
|
-
# Если хочется использовать самую последнюю версию, то можно установить ее через git
|
|
103
|
-
$ pipx install git+https://github.com/s3rgeym/hh-applicant-tool
|
|
104
|
-
|
|
105
|
-
# Для обновления до новой версии
|
|
106
|
-
$ pipx upgrade hh-applicant-tool
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
pipx добавляет исполняемый файл `hh-appplicant-tool` в `~/.local/bin`, делая эту команду доступной. Путь до `~/.local/bin` должен быть в `$PATH` (в большинстве дистрибутивов он добавлен).
|
|
110
|
-
|
|
111
|
-
Традиционный способ для Linux/Mac:
|
|
112
|
-
|
|
113
|
-
```sh
|
|
114
|
-
mkdir -p ~/.venvs
|
|
115
|
-
python -m venv ~/.venvs/hh-applicant-tool
|
|
116
|
-
# Это придется делать постоянно, чтобы команда hh-applicant-tool стала доступна
|
|
117
|
-
. ~/.venvs/hh-applicant-tool/bin/activate
|
|
118
|
-
pip install 'hh-applicant-tool[qt]'
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
Отдельно я распишу процесс установки в **Windows** в подробностях:
|
|
122
|
-
|
|
123
|
-
- Для начала поставьте последнюю версию **Python 3** любым удобным способом.
|
|
124
|
-
- Запустите **Terminal** или **PowerShell** от Администратора и выполните:
|
|
125
|
-
```ps
|
|
126
|
-
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted
|
|
127
|
-
```
|
|
128
|
-
Данная политика разрешает текущему пользователю (от которого зашли) запускать скрипты. Без нее не будут работать виртуальные окружения.
|
|
129
|
-
- Создайте и активируйте виртуальное окружение:
|
|
130
|
-
|
|
131
|
-
```ps
|
|
132
|
-
PS> python -m venv hh-applicant-venv
|
|
133
|
-
PS> .\hh-applicant-venv\Scripts\activate
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
- Поставьте все пакеты в виртуальное окружение `hh-applicant-venv`:
|
|
137
|
-
```ps
|
|
138
|
-
(hh-applicant-venv) PS> pip install hh-applicant-tool[qt]
|
|
139
|
-
```
|
|
140
|
-
- Проверьте работает ли оно:
|
|
141
|
-
```ps
|
|
142
|
-
(hh-applicant-venv) PS> hh-applicant-tool -h
|
|
143
|
-
```
|
|
144
|
-
- В случае неудачи вернитесь к первому шагу.
|
|
145
|
-
- Для последующих запусков сначала активируйте виртуальное окружение.
|
|
146
|
-
|
|
147
|
-
### Авторизация
|
|
148
|
-
|
|
149
|
-
```bash
|
|
150
|
-
$ hh-applicant-tool -vv authorize
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
<img width="610" height="958" alt="image" src="https://github.com/user-attachments/assets/adf47113-df16-4500-aed5-a78d9a783d97" />
|
|
154
|
-
|
|
155
|
-
> Пусть надпись "Поиск содрудников" не вводит в заблуждение — это форма авторизации соискателей. Просто есть долбоебы, которые в этом окне начинают лихорадочно тыкать по ссылкам, не понимая, что форма авторизации у них была перед носом.
|
|
156
|
-
|
|
157
|
-
> В Windows не забудьте разрешить доступ к сети (Allow access) в всплывающем окне.
|
|
158
|
-
|
|
159
|
-
Наиболее частой ошибкой в Windows на этом этапе является высирание ошибок из-за несовместимости определенных версий PyQT6 с системой (в Windows 7 и Windows 8 он вообще вроде не работает):
|
|
160
|
-
|
|
161
|
-
```sh
|
|
162
|
-
js: crbug/1173575, non-JS module files deprecated.
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
Единственное решение в таких случаях попробовать поустанавливать предыдущие или более новые версии `pyqt6` и `pytq6-webengine`:
|
|
166
|
-
|
|
167
|
-
```sh
|
|
168
|
-
pip install --force-reinstall pyqt6==6.X.X pyqt6-webengine==6.X.X
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
Версии этих пакетов должны быть одинаковыми или отличаться минороной версией (последняя цифра через точку), причем `version pyqt6-webengine >= version pyqt6`.
|
|
172
|
-
|
|
173
|
-
Проверка авторизации:
|
|
174
|
-
|
|
175
|
-
```bash
|
|
176
|
-
$ hh-applicant-tool whoami
|
|
177
|
-
{
|
|
178
|
-
"auth_type": "applicant",
|
|
179
|
-
"counters": {
|
|
180
|
-
"new_resume_views": 1488,
|
|
181
|
-
"resumes_count": 1,
|
|
182
|
-
"unread_negotiations": 228
|
|
183
|
-
},
|
|
184
|
-
"email": "vasya.pupkin@gmail.com",
|
|
185
|
-
"employer": null,
|
|
186
|
-
"first_name": "Вася",
|
|
187
|
-
"id": "1234567890",
|
|
188
|
-
"is_admin": false,
|
|
189
|
-
"is_anonymous": false,
|
|
190
|
-
"is_applicant": true,
|
|
191
|
-
"is_application": false,
|
|
192
|
-
"is_employer": false,
|
|
193
|
-
"is_in_search": true,
|
|
194
|
-
"last_name": "Пупкин",
|
|
195
|
-
"manager": null,
|
|
196
|
-
"mid_name": null,
|
|
197
|
-
"middle_name": null,
|
|
198
|
-
"negotiations_url": "https://api.hh.ru/negotiations",
|
|
199
|
-
"personal_manager": null,
|
|
200
|
-
"phone": "79012345678",
|
|
201
|
-
"profile_videos": {
|
|
202
|
-
"items": []
|
|
203
|
-
},
|
|
204
|
-
"resumes_url": "https://api.hh.ru/resumes/mine"
|
|
205
|
-
}
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
В случае успешной авторизации токены будут сохранены в `config.json`:
|
|
209
|
-
|
|
210
|
-
```json
|
|
211
|
-
{
|
|
212
|
-
"token": {
|
|
213
|
-
"access_token": "...",
|
|
214
|
-
"created_at": 1678151427,
|
|
215
|
-
"expires_in": 1209599,
|
|
216
|
-
"refresh_token": "...",
|
|
217
|
-
"token_type": "bearer"
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
Токен доступа выдается на две недели. Он обновляется автоматически. Для его ручного обновления нужно выполнить:
|
|
223
|
-
|
|
224
|
-
```bash
|
|
225
|
-
$ hh-applicant-tool refresh-token
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
Помните, что у `refresh_token` тоже есть время жизни, поэтому может потребоваться полная авторизация.
|
|
229
|
-
|
|
230
|
-
### Пути до файла config.json
|
|
231
|
-
|
|
232
|
-
| OS | Путь |
|
|
233
|
-
| ----------- | ------------------------------------------------------------------- |
|
|
234
|
-
| **Windows** | `C:\Users\%username%\AppData\Roaming\hh-applicant-tool\config.json` |
|
|
235
|
-
| **macOS** | `~/Library/Application Support/hh-applicant-tool/config.json` |
|
|
236
|
-
| **Linux** | `~/.config/hh-applicant-tool/config.json` |
|
|
237
|
-
|
|
238
|
-
Полный путь до конфигурационного файла можно вывести с помощью команды:
|
|
239
|
-
|
|
240
|
-
```bash
|
|
241
|
-
hh-applicant-tool config -p
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
Через конфиг можно задать дополнительные настройки:
|
|
245
|
-
|
|
246
|
-
| Имя атрибута | Описание |
|
|
247
|
-
| --------------- | ------------------------------------------------------------------------------------------ |
|
|
248
|
-
| `proxy_url` | Прокси, используемый для всех запросов, например, `socks5h://127.0.0.1:9050` |
|
|
249
|
-
| `reply_message` | Сообщение для ответа работодателю при отклике на вакансии, см. формат сообщений |
|
|
250
|
-
| `user_agent` | Кастомный юзерагент, передаваемый при каждом запросе. По умолчанию используется от Android |
|
|
251
|
-
| `client_id` | Идентификатор клиента, используемый для авторизации. По умолчанию используется от Android |
|
|
252
|
-
| `client_secret` | Секретный ключ клиента, используемый для авторизации. По умолчанию используется от Android |
|
|
253
|
-
|
|
254
|
-
### Описание команд
|
|
255
|
-
|
|
256
|
-
```bash
|
|
257
|
-
$ hh-applicant-tool [ GLOBAL_FLAGS ] [ OPERATION [ OPERATION_FLAGS ] ]
|
|
258
|
-
|
|
259
|
-
# Справка по глобальным флагам и список операций
|
|
260
|
-
$ hh-applicant-tool -h
|
|
261
|
-
|
|
262
|
-
# Справка по операции
|
|
263
|
-
$ hh-applicant-tool apply-similar -h
|
|
264
|
-
|
|
265
|
-
# Авторизуемся
|
|
266
|
-
$ hh-applicant-tool authorize
|
|
267
|
-
|
|
268
|
-
# Рассылаем заявки
|
|
269
|
-
$ hh-applicant-tool apply-similar
|
|
270
|
-
|
|
271
|
-
# Поднимаем резюме
|
|
272
|
-
$ hh-applicant-tool update-resumes
|
|
273
|
-
|
|
274
|
-
# Чистим заявки и баним за отказы говноконторы
|
|
275
|
-
$ hh-applicant-tool clear-negotiations --blacklist-discard
|
|
276
|
-
|
|
277
|
-
# Экспортировать в HTML, контакты работодателей, которые когда-либо высылали вам
|
|
278
|
-
# приглашение
|
|
279
|
-
$ hh-applicant-tool get-employer-contacts --export -f html > report.html
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
Можно вызвать любой метод API:
|
|
283
|
-
|
|
284
|
-
```bash
|
|
285
|
-
$ hh-applicant-tool call-api /employers text="IT" only_with_vacancies=true | jq -r '.items[].alternate_url'
|
|
286
|
-
https://hh.ru/employer/1966364
|
|
287
|
-
https://hh.ru/employer/4679771
|
|
288
|
-
https://hh.ru/employer/8932785
|
|
289
|
-
https://hh.ru/employer/9451699
|
|
290
|
-
https://hh.ru/employer/766478
|
|
291
|
-
https://hh.ru/employer/4168187
|
|
292
|
-
https://hh.ru/employer/9274777
|
|
293
|
-
https://hh.ru/employer/1763330
|
|
294
|
-
https://hh.ru/employer/5926815
|
|
295
|
-
https://hh.ru/employer/1592535
|
|
296
|
-
https://hh.ru/employer/9627641
|
|
297
|
-
https://hh.ru/employer/4073857
|
|
298
|
-
https://hh.ru/employer/2667859
|
|
299
|
-
https://hh.ru/employer/4053700
|
|
300
|
-
https://hh.ru/employer/5190600
|
|
301
|
-
https://hh.ru/employer/607484
|
|
302
|
-
https://hh.ru/employer/9386615
|
|
303
|
-
https://hh.ru/employer/80660
|
|
304
|
-
https://hh.ru/employer/6078902
|
|
305
|
-
https://hh.ru/employer/1918903
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
Данная возможность полезна для написания Bash-скриптов.
|
|
309
|
-
|
|
310
|
-
Глобальные флаги:
|
|
311
|
-
|
|
312
|
-
- `-v` используется для вывода отладочной информации. Два таких флага, например, выводят запросы к **API**.
|
|
313
|
-
- `-c <path>` можно создать путь до конфига. С помощью этого флага можно одновременно использовать несколько профилей.
|
|
314
|
-
|
|
315
|
-
| Операция | Описание |
|
|
316
|
-
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
317
|
-
| **authorize** | Открывает сайт hh.ru для авторизации и перехватывает перенаправление на `hhadnroid://oauthresponse` |
|
|
318
|
-
| **whoami** | Выводит информацию об авторизованном пользователе |
|
|
319
|
-
| **list-resumes** | Список резюме |
|
|
320
|
-
| **update-resumes** | Обновить все резюме. Аналогично нажатию кнопки «Обновить дату». |
|
|
321
|
-
| **apply-similar** | Откликнуться на все подходящие вакансии. Лимит = 200 в день. На HH есть спам-фильтры, так что лучше не рассылайте отклики со ссылками, иначе рискуете попасть в теневой бан. |
|
|
322
|
-
| **reply-employers** | Ответить во все чаты с работодателями, где нет ответа либо не прочитали ваш предыдущий ответ |
|
|
323
|
-
| **clear-negotiations** | Удаляет отказы и отменяет заявки, которые долго висят |
|
|
324
|
-
| **call-api** | Вызов произвольного метода API с выводом результата. |
|
|
325
|
-
| **refresh-token** | Обновляет access_token. |
|
|
326
|
-
| **config** | Редактировать конфигурационный файл. |
|
|
327
|
-
| **get-employer-contacts** | Получить список полученных вами контактов работодателей. Поддерживается так же экспорт в html/jsonl. Если хотите собирать контакты с нескольких акков, то укажите им одинаковый `client_telemetry_id` в конфигах. |
|
|
328
|
-
| **delete-telemetry** | Удадяет телеметрию (контакты работодателей, которые вас пригласили), если та была включена. |
|
|
329
|
-
|
|
330
|
-
Данные имена команд равнозначны: `call-api = callApi = callapi`. Можно использовать `kebab-case`, `camelCase` и `flatcase`.
|
|
331
|
-
|
|
332
|
-
### Формат текста сообщений
|
|
333
|
-
|
|
334
|
-
Команда `apply-similar` поддерживает специальный формат сообщений.
|
|
335
|
-
|
|
336
|
-
Так же в сообщении можно использовать плейсхолдеры:
|
|
337
|
-
|
|
338
|
-
- **`%(vacancy_name)s`**: Название вакансии.
|
|
339
|
-
- **`%(employer_name)s`**: Название работодателя.
|
|
340
|
-
- **`%(first_name)s`**: Имя пользователя.
|
|
341
|
-
- **`%(last_name)s`**: Фамилия пользователя.
|
|
342
|
-
- **`%(email)s`**: Email пользователя.
|
|
343
|
-
- **`%(phone)s`**: Телефон пользователя.
|
|
344
|
-
|
|
345
|
-
Эти плейсхолдеры могут быть использованы в сообщениях для отклика на вакансии, чтобы динамически подставлять соответствующие данные в текст сообщения. Например:
|
|
346
|
-
|
|
347
|
-
```
|
|
348
|
-
Меня заинтересовала ваша вакансия %(vacancy_name)s. Прошу рассмотреть мою кандидатуру. С уважением, %(first_name)s %(last_name)s.
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
Так же можно делать текст уникальным с помощью `{}`. Внутри них через `|` перечисляются варианты, один из которых будет случайно выбран:
|
|
352
|
-
|
|
353
|
-
```
|
|
354
|
-
{Здоров|Привет}, {как {ты|сам}|что делаешь}?
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
В итоге получится что-то типа:
|
|
358
|
-
|
|
359
|
-
```
|
|
360
|
-
Привет, как ты?
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
### Использование AI для генерации сопроводительного письма
|
|
364
|
-
|
|
365
|
-
Пример рассылки откликов с генерированным письмом:
|
|
366
|
-
|
|
367
|
-
```sh
|
|
368
|
-
hh-applicant-tool apply-similar -f --ai
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
#### OpenAI/ChatGPT
|
|
372
|
-
|
|
373
|
-
Отредактируйте конфиг:
|
|
374
|
-
|
|
375
|
-
```json
|
|
376
|
-
{
|
|
377
|
-
// ...
|
|
378
|
-
"openai": {
|
|
379
|
-
"token": "ВАШ_API_КЛЮЧ_OPENAI",
|
|
380
|
-
"model": "gpt-4o",
|
|
381
|
-
"system_prompt": "Вы опытный HR-специалист. Напишите идеальное сопроводительное письмо..."
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
```
|
|
385
|
-
|
|
386
|
-
#### Эксперементальная поддержка BlackBox
|
|
387
|
-
|
|
388
|
-
> Поддержка Blackbox будет удалена.
|
|
389
|
-
|
|
390
|
-
- Перейдите на сайт [blackbox.ai](https://www.blackbox.ai) и создайте чат.
|
|
391
|
-
- В первом сообщении опишите свой опыт и тп.
|
|
392
|
-
- Далее откройте devtools, нажав `F12`.
|
|
393
|
-
- Во вкладке `Network` последним должен быть POST-запрос на `https://www.blackbox.ai/api/chat`.
|
|
394
|
-
- Запустите редактирование конфига:
|
|
395
|
-
```sh
|
|
396
|
-
hh-applicant-tool config
|
|
397
|
-
```
|
|
398
|
-
- Измените конфиг:
|
|
399
|
-
```json
|
|
400
|
-
{
|
|
401
|
-
// ...
|
|
402
|
-
"blackbox": {
|
|
403
|
-
"session_id": "<В заголовках запроса найдите Cookie, скопируйте сюда значение sessionId до ;>",
|
|
404
|
-
"chat_payload": <Сюда вставьте тело запроса типа {"messages":[{"id":"IXqdOx9","content":"Я программист fullstack-разработчик...","role":"user"}],"id":"IXqdOx9","previewToken":null,"userId":null,...,"webSearchModePrompt":false,"deepSearchMode":false}>
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
### Работа с API напрямую
|
|
410
|
-
|
|
411
|
-
Документация для работы с API соискателей была удалена с ха-ха и его копропротивного репозитория. Можете не искать, они затерли даже историю репозитория. Но я через веб-архив выкачал документацию. Чтобы ее посмотреть, клонируйте этот репозиторий и выполните:
|
|
412
|
-
|
|
413
|
-
```sh
|
|
414
|
-
npx @redocly/cli preview -d docs/hhapi
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
Далее нужно в браузере открыть [http://localhost:4000](http://localhost:4000).
|
|
418
|
-
|
|
419
|
-
<img width="2560" height="1440" alt="image" src="https://github.com/user-attachments/assets/a963b405-b872-4865-abed-fd704532cd80" />
|
|
420
|
-
|
|
421
|
-
> Отдельные замечания у меня к API HH. Оно пиздец какое кривое. Например, при создании заявки возвращается пустой ответ либо редирект, хотя по логике должен возвраться созданный объект. Так же в ответах сервера нет `Content-Length`. Из-за этого нельзя узнать есть тело у ответа сервера нужно его пробовать прочитать. Я так понял там какой-то прокси оборачивает все запросы и отдает всегда `Transfer-Encoding: Chunked`. А еще он возвращает 502 ошибку, когда бекенд на Java падает либо долго отвечает (таймаут)? А вот [язык запросов](https://hh.ru/article/1175) мне понравился. Можно что-то типа этого использовать `NOT (!ID:123 OR !ID:456 OR !ID:789)` что бы отсеить какие-то вакансии.
|
|
422
|
-
|
|
423
|
-
Для тестирования запросов к API используйте команду `call-api` и `jq` для вывода JSON в удобочитаемом формате. По-сути, никакие дополнительные команды кроме имеющихся не нужны. Вы можете сделать что угодно с помощью `call-api`.
|
|
424
|
-
|
|
425
|
-
Синтаксис `call-api` немного похож на `httpie` или `curlie`:
|
|
426
|
-
|
|
427
|
-
```sh
|
|
428
|
-
hh-applicant-tool call-api [ -m {GET|POST|PUT|DELETE} ] /path/to/endpoint [ key1=value1 [ ... keyN=valueN ] ]
|
|
429
|
-
```
|
|
430
|
-
|
|
431
|
-
Если используется метод `GET` или `DELETE` (или ничего не указано), то параметры будут переданы как query string. Во всех остальных случаях парметры передаются как `application/x-www-form-urlencoded` в теле запроса.
|
|
432
|
-
|
|
433
|
-
Пример блокировки контактов мошенников:
|
|
434
|
-
|
|
435
|
-
```sh
|
|
436
|
-
# Делаем дамп ваших контактов
|
|
437
|
-
hh-applicant-tool get-employer-contacts --export -f jsonl > contacts.dump
|
|
438
|
-
|
|
439
|
-
# Теперь блокируем всех мошенников
|
|
440
|
-
jq -r 'select(.is_scam == true) | .employer.id' contacts.dump | sort -u | xargs -I {} hh-applicant-tool call-api -m PUT /employers/blacklisted/{}
|
|
441
|
-
|
|
442
|
-
# И императивная версия
|
|
443
|
-
for id in $(jq -r 'select(.is_scam == true) | .employer.id' contacts.dump | sort -u); do
|
|
444
|
-
hh-applicant-tool call-api -m PUT "/employers/blacklisted/$id"
|
|
445
|
-
done
|
|
446
|
-
```
|
|
447
|
-
|
|
448
|
-
### Добавление своих команд
|
|
449
|
-
|
|
450
|
-
Утилита использует систему плагинов. Все они лежат в [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).
|
|
451
|
-
|
|
452
|
-
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
hh_applicant_tool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
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
|
|
5
|
-
hh_applicant_tool/ai/openai.py,sha256=sTzxiuOq7NyQb3T-KVwTxQkdGbZa3JniNIkvHpMHAKw,1831
|
|
6
|
-
hh_applicant_tool/api/__init__.py,sha256=kgFSHibRaAugN2BA3U1djEa20qgKJUUVouwJzjEB0DU,84
|
|
7
|
-
hh_applicant_tool/api/client.py,sha256=ReBcVRnL9J1lDSYbJVFN_taY9qDmumAtMO7bLkDDcco,9998
|
|
8
|
-
hh_applicant_tool/api/errors.py,sha256=xY35IFA-Uf7at5iBYDkcPN3rzhWA1JwpqAVYLPrPPo8,1869
|
|
9
|
-
hh_applicant_tool/color_log.py,sha256=dVzGcPl-uKAyDMM_lI0dH4KHP3etDVp5Q87QEkPdxdA,1240
|
|
10
|
-
hh_applicant_tool/constants.py,sha256=KV_jowi21ToMp8yqF1vWolnVZb8nAC3rYRkcFJ71m-Q,759
|
|
11
|
-
hh_applicant_tool/jsonc.py,sha256=QNS4gRHfi7SAeOFnffAIuhH7auC4Y4HAkmH12eX5PkI,4002
|
|
12
|
-
hh_applicant_tool/main.py,sha256=V57U1Mmduhw5aScsmdckiuoU9E5EIlpQiRQXKSNF7pk,7007
|
|
13
|
-
hh_applicant_tool/mixins.py,sha256=8VoyrNgdlljy6pLTSFGJOYd9kagWT3yFOZYIGR6MEbI,425
|
|
14
|
-
hh_applicant_tool/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
hh_applicant_tool/operations/apply_similar.py,sha256=Ybe8QYijjCdF20nhXXqFycf6RaeV6ldAL35wmQFHXNM,25741
|
|
16
|
-
hh_applicant_tool/operations/authorize.py,sha256=ZBkJUXqlygLz56_BRfR8aa06SvWbnKc8ilXki4noAME,4703
|
|
17
|
-
hh_applicant_tool/operations/call_api.py,sha256=o3GZgtqk6w4zpCm-JTHVjFrKVOwW-vsu1HdRi-hqAjo,1423
|
|
18
|
-
hh_applicant_tool/operations/clear_negotiations.py,sha256=457NI6P6msAzenbUPaX5ZY2lTgPrdqYKmwkRQp4mmks,4427
|
|
19
|
-
hh_applicant_tool/operations/config.py,sha256=oPGz-gcqmeOJwkUK3DUwl5HjYLbWZc2dDPrlIP4VOEM,1340
|
|
20
|
-
hh_applicant_tool/operations/delete_telemetry.py,sha256=JHdh_l7IJL_qy5AIIy8FQpUupmH60D3a6zjfEVKkT2U,986
|
|
21
|
-
hh_applicant_tool/operations/get_employer_contacts.py,sha256=Wv04PccQsGctW-tE-hHVnIfPU1do1AtIwOErSIeXqno,11810
|
|
22
|
-
hh_applicant_tool/operations/list_resumes.py,sha256=dILHyBCSEVqdNAvD8SML5f2Lau1R2AzTaKE9B4FG8Wg,1109
|
|
23
|
-
hh_applicant_tool/operations/refresh_token.py,sha256=v_Fcw9mCfOdE6MLTCQjZQudhJPX0fup3k0BaIM394Qw,834
|
|
24
|
-
hh_applicant_tool/operations/reply_employers.py,sha256=40rsTgpoEUaRQUq5ZQYgojKb42smYRkbDDD2S_7Vwtg,13512
|
|
25
|
-
hh_applicant_tool/operations/update_resumes.py,sha256=_r7HA_vpYMs5DFY-mVP1ZRG9bggsv7ebKYrwteBmJ30,1053
|
|
26
|
-
hh_applicant_tool/operations/whoami.py,sha256=pNWJMmEQLBk3U6eiGz4CHcX7eXzDXcfezFjX7zLjqyA,711
|
|
27
|
-
hh_applicant_tool/telemetry_client.py,sha256=I1CdsjJzKNRgAPG11CSDw8AtSYQbCB2Ry3076qneA6U,3833
|
|
28
|
-
hh_applicant_tool/types.py,sha256=sQbt_vGXtWPRJ3UzcUkE87BTHOaGTsFxqdZa_qFghZE,864
|
|
29
|
-
hh_applicant_tool/utils.py,sha256=jvl75e-vyR2pxqQ-oqzb2sfNFwHxexHZOgbjwfIwBaQ,3536
|
|
30
|
-
hh_applicant_tool-0.7.10.dist-info/METADATA,sha256=jJg3MiHanZzlgydNa-4aXQThZIgHncqbV5DLL7obuBM,32168
|
|
31
|
-
hh_applicant_tool-0.7.10.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
32
|
-
hh_applicant_tool-0.7.10.dist-info/entry_points.txt,sha256=Vb7M2YaYLMtKYJZh8chIrXZApMzSRFT1-rQw-U9r10g,65
|
|
33
|
-
hh_applicant_tool-0.7.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|