Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Akhil main cleanup #41

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.template
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
PYTHONPATH=${PYTHONPATH}:${workspaceFolder}/src
# refer to docs: [getting_web_search_engine_creds.md](docs/getting_web_search_engine_creds.md)
GOOGLE_API_KEY=
GOOGLE_SEARCH_ENGINE_ID=
Expand Down
25 changes: 0 additions & 25 deletions .github/workflows/ci.yml

This file was deleted.

4 changes: 3 additions & 1 deletion .github/workflows/py_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ on:
push:
branches:
- '**'
pull_request:
pull_request_target:
branches:
- main
types: [opened, synchronize, reopened]

jobs:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/test_env_setup_and_run_workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,6 @@ jobs:
- name: Run tests with PyTest configuration
env:
PYTHONPATH: ${{ env.PYTHONPATH }} # Explicitly pass PYTHONPATH to the test environment
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} # Pass the Google API key as an environment variable
GOOGLE_SEARCH_ENGINE_ID: ${{ secrets.GOOGLE_SEARCH_ENGINE_ID }} # Pass the Google Search Engine ID as an environment variable
run: ${{ inputs.test_command }}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ Before you begin, ensure you have met the following requirements:

### Download and Install Python

Ensure you have the latest Python version installed (Python 3.8 or higher is required for Poetry). If not, download and install it from Python's official website. For detailed instructions, refer to the tutorials:
Ensure you have the latest Python version installed (Python 3.11 or higher is required for this project). If not, download and install it from Python's official website. For detailed instructions, refer to the tutorials:
- [How to Install Python on Windows](https://docs.python.org/3/using/windows.html)
- [How to Install Python on Linux](https://docs.python.org/3/using/unix.html)
- [How to Download and Install Python on macOS](https://docs.python.org/3/using/mac.html)
Expand Down
4 changes: 3 additions & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ minversion = 6.0
addopts = --strict-markers --tb=short --cov=src --cov-report=term-missing
testpaths =
tests
pythonpath = src
pythonpath =
src
.
env =
ENV=test
env_files =
Expand Down
4 changes: 2 additions & 2 deletions src/ai_hawk/job_applier.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
from job_portals.base_job_portal import BaseJobPage, BaseJobPortal


from src.job import Job
from src.ai_hawk.llm.llm_manager import GPTAnswerer
from job import Job
from ai_hawk.llm.llm_manager import GPTAnswerer
from utils import browser_utils, time_utils


Expand Down
10 changes: 5 additions & 5 deletions src/ai_hawk/llm/llm_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
from Levenshtein import distance
from loguru import logger

import src.ai_hawk.llm.prompts as prompts
from src.config import JOB_SUITABILITY_SCORE
from src.constants import (
import ai_hawk.llm.prompts as prompts
from config import JOB_SUITABILITY_SCORE
from constants import (
AVAILABILITY,
CERTIFICATIONS,
CLAUDE,
Expand Down Expand Up @@ -72,9 +72,9 @@
USAGE_METADATA,
WORK_PREFERENCES,
)
from src.job import Job
from job import Job

import src.config as cfg
import config as cfg

load_dotenv()

Expand Down
4 changes: 2 additions & 2 deletions src/jobContext.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from src.job import Job
from src.job_application import JobApplication
from job import Job
from job_application import JobApplication


from dataclasses import dataclass
Expand Down
2 changes: 1 addition & 1 deletion src/job_application.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from src.job import Job
from job import Job

class JobApplication:

Expand Down
15 changes: 6 additions & 9 deletions src/job_portals/base_job_portal.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
from re import A

from constants import LEVER, LINKEDIN
from src.job_portals.application_form_elements import SelectQuestion, TextBoxQuestion
from src.ai_hawk.authenticator import AIHawkAuthenticator
from src.job import Job
from src.jobContext import JobContext
from job_portals.application_form_elements import SelectQuestion, TextBoxQuestion
from ai_hawk.authenticator import AIHawkAuthenticator
from job import Job
from jobContext import JobContext

from selenium.webdriver.remote.webelement import WebElement
from typing import List, TypeVar
Expand Down Expand Up @@ -214,19 +214,16 @@ def application_page(self) -> BaseApplicationPage:


def get_job_portal(portal_name, driver, work_preferences):
from src.job_portals.linkedIn.linkedin import LinkedIn
from src.job_portals.lever.lever import Lever
from job_portals.lever.lever import Lever

if portal_name == LEVER:
return Lever(driver, work_preferences)
elif portal_name == LINKEDIN:
return LinkedIn(driver, work_preferences)
else:
raise ValueError(f"Unknown job portal: {portal_name}")


def get_authenticator(driver, platform):
from src.job_portals.linkedIn.authenticator import LinkedInAuthenticator
from job_portals.linkedIn.authenticator import LinkedInAuthenticator

if platform == LINKEDIN:
return LinkedInAuthenticator(driver)
Expand Down
4 changes: 2 additions & 2 deletions src/job_portals/lever/application_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
from selenium.webdriver.remote.webelement import WebElement
from custom_exception import JobSkipException
from logger import logger
from src.job_portals.application_form_elements import (
from job_portals.application_form_elements import (
SelectQuestion,
SelectQuestionType,
TextBoxQuestion,
TextBoxQuestionType,
)
from src.job_portals.base_job_portal import BaseApplicationPage
from job_portals.base_job_portal import BaseApplicationPage
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException, ElementClickInterceptedException

Expand Down
2 changes: 1 addition & 1 deletion src/job_portals/lever/authenticator.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from src.ai_hawk.authenticator import AIHawkAuthenticator
from ai_hawk.authenticator import AIHawkAuthenticator

class LeverAuthenticator(AIHawkAuthenticator):

Expand Down
3 changes: 2 additions & 1 deletion src/job_portals/lever/job_page.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import traceback
from loguru import logger
from custom_exception import JobNotSuitableException, JobSkipException
from src.job_portals.base_job_portal import BaseJobPage
from job_portals.base_job_portal import BaseJobPage
from selenium.webdriver.common.by import By

from utils import time_utils
Expand All @@ -15,6 +15,7 @@ def __init__(self, driver):
def goto_job_page(self, job):
try:
self.driver.get(job.link)
time_utils.medium_sleep()
logger.debug(f"Navigated to job link: {job.link}")
except Exception as e:
logger.error(f"Failed to navigate to job link: {job.link}, error: {str(e)}")
Expand Down
8 changes: 4 additions & 4 deletions src/job_portals/lever/jobs_page.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from typing import List, Optional
from constants import COMPANY
from src.job import Job, JobState
from src.job_portals.base_job_portal import BaseJobsPage
from src.logger import logger
from job import Job, JobState
from job_portals.base_job_portal import BaseJobsPage
from logger import logger
import stringcase
from src.services.web_search_engine import SearchQueryBuilder, SearchResult, SearchTimeRange, WebSearchEngine, WebSearchEngineFactory
from services.web_search_engine import SearchQueryBuilder, SearchResult, SearchTimeRange, WebSearchEngine, WebSearchEngineFactory


class SearchLeverJobs(BaseJobsPage):
Expand Down
10 changes: 5 additions & 5 deletions src/job_portals/lever/lever.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import re
from src.job_portals.base_job_portal import BaseJobPortal
from src.job_portals.lever.authenticator import LeverAuthenticator
from src.job_portals.lever.jobs_page import SearchLeverJobs
from src.job_portals.lever.application_page import LeverApplicationPage
from src.job_portals.lever.job_page import LeverJobPage
from job_portals.base_job_portal import BaseJobPortal
from job_portals.lever.authenticator import LeverAuthenticator
from job_portals.lever.jobs_page import SearchLeverJobs
from job_portals.lever.application_page import LeverApplicationPage
from job_portals.lever.job_page import LeverJobPage

class Lever(BaseJobPortal):

Expand Down
4 changes: 2 additions & 2 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
WORK_PREFERENCES_YAML,
WORK_PREFERENCES,
)
from src.job_portals.base_job_portal import get_job_portal
from src.utils.chrome_utils import chrome_browser_options
from job_portals.base_job_portal import get_job_portal
from utils.chrome_utils import chrome_browser_options

from job_application_profile import JobApplicationProfile
from logger import logger
Expand Down
20 changes: 14 additions & 6 deletions src/services/web_search_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import requests
from abc import ABC, abstractmethod

import src.config as config
from src.config import ALLOWED_SEARCH_ENGINES, GOOGLE, BING, BRAVE
from src.logger import logger
import config as config
from config import ALLOWED_SEARCH_ENGINES, GOOGLE, BING, BRAVE
from logger import logger

@dataclass
class SearchResult:
Expand Down Expand Up @@ -206,7 +206,10 @@ def __init__(self):
self.api_key = config.GOOGLE_API_KEY
self.search_engine_id = config.GOOGLE_SEARCH_ENGINE_ID

def search(self, query: str, params: dict = {}, offset: int = 0, limit: int = DEFAULT_SEARCH_LIMIT) -> PaginatedSearchResponse:
def search(self, query: str, params: dict = {}, offset: int = 0, limit: Optional[int] = None) -> PaginatedSearchResponse:

if limit is None:
limit = self.DEFAULT_SEARCH_LIMIT
"""
Google uses 'start' to represent offset.
If offset is 0, start=1. If offset is 10, start=11, etc.
Expand Down Expand Up @@ -291,10 +294,13 @@ def DEFAULT_SEARCH_LIMIT(self) -> int:
def __init__(self):
self.api_key = config.BING_API_KEY

def search(self, query: str, params: dict = {}, offset: int = 0, limit: int = DEFAULT_SEARCH_LIMIT) -> PaginatedSearchResponse:
def search(self, query: str, params: dict = {}, offset: int = 0, limit: Optional[int] = None) -> PaginatedSearchResponse:
"""
Bing uses 'offset' in addition to 'count' (our limit).
"""
if limit is None:
limit = self.DEFAULT_SEARCH_LIMIT

headers = {"Ocp-Apim-Subscription-Key": self.api_key}
params.update({
"q": query,
Expand Down Expand Up @@ -369,7 +375,9 @@ def DEFAULT_SEARCH_LIMIT(self) -> int:
def __init__(self):
self.api_key = config.BRAVE_API_KEY

def search(self, query: str, params: dict = {}, offset: int = 0, limit: int = DEFAULT_SEARCH_LIMIT) -> PaginatedSearchResponse:
def search(self, query: str, params: dict = {}, offset: int = 0, limit: Optional[int] = None) -> PaginatedSearchResponse:
if limit is None:
limit = self.DEFAULT_SEARCH_LIMIT
"""
Brave also supports 'offset' (number of items to skip) and 'limit'.
"""
Expand Down
2 changes: 1 addition & 1 deletion src/utils/browser_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import pygame
import constants

# Module-level variable to store the default driver
# Module-level variable to store the default driver, make sure your imports are exactly same when you are using this
__DEFAULT_DRIVER: Optional[webdriver.Chrome] = None


Expand Down
2 changes: 1 addition & 1 deletion tests/integration/test_web_search_engine_integration.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pytest
from src.services.web_search_engine import GoogleSearchEngine, BingSearchEngine, BraveSearchEngine
from services.web_search_engine import GoogleSearchEngine, BingSearchEngine, BraveSearchEngine

@pytest.mark.integration
def test_google_search_engine_integration():
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/test_aihawk_job_manager.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# import json
# import re
# from src.job import Job
# from job import Job
# from unittest import mock
# from pathlib import Path
# import os
# import pytest
# from ai_hawk.job_manager import AIHawkJobManager
# from selenium.common.exceptions import NoSuchElementException
# from src.logging import logger
# from logging import logger


# @pytest.fixture
Expand Down
Loading
Loading