diff --git a/README.md b/README.md
index 32da93c..1c34095 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,7 @@
-
+
MagicalAPI Python Client
@@ -34,8 +34,8 @@
-
View Demo
- ·
+
+
Report Bug
·
Request Feature
@@ -75,7 +75,7 @@
## What is [MagicalAPI][website-url]?
-MagicalAPI is your AI edge in **content** and **careers**, Your ultimate tool for **YouTube SEO**, **Resume Parsing**, **LinkedIn data** and more.
+MagicalAPI is your AI edge in **content** and **careers**, Your ultimate tool for **Resume Parsing**, **LinkedIn data** and more.
@@ -149,44 +149,43 @@ client = AsyncClinet()
-Here is an example of how to get keywords of [Youtube Top Keywords](https://magicalapi.com/services/youtube-keywords) service:
+Here is an example of how to parse a resume using [Resume Parser](https://magicalapi.com/resume/) service:
```python
import asyncio
+
from magicalapi.client import AsyncClient
+from magicalapi.errors import APIServerError, APIServerTimedout
from magicalapi.types.base import ErrorResponse
-search_sentence = "chatgpt 4 turbo" # your search sentence to get keywords related to
-country = "1" # use get_countries method to see countries codes (Default = 1 : WorlWide)
-language = "1000" # use get_languages method to see countries codes (Default = 1000 : English)
+resume_url = (
+ "https://resume-resource.com/wp-content/uploads/00123-sales-professional-resume.pdf"
+)
+output_file_name = "resume_parser.json"
async def main():
- # the api_key will load from the .env file
- async with AsyncClient() as client:
- # Get YouTube keywords
- keywords_response = await client.youtube_top_keywords.get_keywords(
- search_sentence=search_sentence,
- country=country,
- language=language,
- )
- if type(keywords_response) == ErrorResponse:
- # got error from API
- print("Error :", keywords_response.message)
- else:
- # got response successfully
- print("credits :", keywords_response.usage.credits)
- print("keywords count :", len(keywords_response.data.keywords))
-
- # save response in JSON file
- with open("keywords_response.json", "w") as file:
- file.write(keywords_response.model_dump_json(indent=3))
-
-
- # get languages list
- # languages = await client.youtube_top_keywords.get_languages()
- # get countries list
- # countries = await client.youtube_top_keywords.get_countries()
+ try:
+ # the api_key will load from the .env file
+ async with AsyncClient() as client:
+ response = await client.resume_parser.get_resume_parser(url=resume_url)
+
+ if isinstance(response, ErrorResponse):
+ # got error from api
+ print("Error :", response.message)
+ else:
+ # got response successfully
+ print("credists :", response.usage.credits)
+ # save response in json file
+ with open(output_file_name, "w") as file:
+ file.write(response.model_dump_json(indent=3))
+
+ print(f"response saved to {output_file_name}")
+ except (APIServerError, APIServerTimedout) as e:
+ # handling server errors
+ print(e)
+ except Exception as e:
+ print("An error occurred:", str(e))
asyncio.run(main())
diff --git a/docs/logo.jpg b/docs/logo.jpg
deleted file mode 100644
index 949ca8a..0000000
Binary files a/docs/logo.jpg and /dev/null differ
diff --git a/docs/logo.png b/docs/logo.png
index e0f4c1c..66e2236 100644
Binary files a/docs/logo.png and b/docs/logo.png differ
diff --git a/examples/youtube_seo.py b/examples/youtube_seo.py
deleted file mode 100644
index 69eedee..0000000
--- a/examples/youtube_seo.py
+++ /dev/null
@@ -1,35 +0,0 @@
-import asyncio
-
-from magicalapi.client import AsyncClient
-from magicalapi.errors import APIServerError, APIServerTimedout
-from magicalapi.types.base import ErrorResponse
-
-video_url = "https://www.youtube.com/watch?v=PZZI1QXlM80"
-output_file_name = "youtube_seo.json"
-
-
-async def main():
- try:
- # the api_key will load from the .env file
- async with AsyncClient() as client:
- response = await client.youtube_seo.get_youtube_seo(url=video_url)
-
- if isinstance(response, ErrorResponse):
- # got error from api
- print("Error :", response.message)
- else:
- # got response successfully
- print("credists :", response.usage.credits)
- # save response in json file
- with open(output_file_name, "w") as file:
- file.write(response.model_dump_json(indent=3))
-
- print(f"response saved to {output_file_name}")
- except (APIServerError, APIServerTimedout) as e:
- # handling server errors
- print(e)
- except Exception as e:
- print("An error occurred:", str(e))
-
-
-asyncio.run(main())
diff --git a/examples/youtube_suggestions.py b/examples/youtube_suggestions.py
deleted file mode 100644
index 3dc7a94..0000000
--- a/examples/youtube_suggestions.py
+++ /dev/null
@@ -1,41 +0,0 @@
-import asyncio
-
-from magicalapi.client import AsyncClient
-from magicalapi.errors import APIServerError, APIServerTimedout
-from magicalapi.types.base import ErrorResponse
-
-prompt_sentence = "How to create a profitable Shopify store"
-count = 5
-suggestion_goal = "hashtag"
-output_file_name = "youtube_suggestions.json"
-
-
-async def main():
- try:
- # the api_key will load from the .env file
- async with AsyncClient() as client:
- response = await client.youtube_suggestions.get_youtube_suggestions(
- prompt_sentence=prompt_sentence,
- count=count,
- suggestion_goal=suggestion_goal,
- )
-
- if isinstance(response, ErrorResponse):
- # got error from api
- print("Error :", response.message)
- else:
- # got response successfully
- print("credists :", response.usage.credits)
- # save response in json file
- with open(output_file_name, "w") as file:
- file.write(response.model_dump_json(indent=3))
-
- print(f"response saved to {output_file_name}")
- except (APIServerError, APIServerTimedout) as e:
- # handling server errors
- print(e)
- except Exception as e:
- print("An error occurred:", str(e))
-
-
-asyncio.run(main())
diff --git a/examples/youtube_top_keywords.py b/examples/youtube_top_keywords.py
deleted file mode 100644
index 204a516..0000000
--- a/examples/youtube_top_keywords.py
+++ /dev/null
@@ -1,51 +0,0 @@
-import asyncio
-
-from magicalapi.client import AsyncClient
-from magicalapi.errors import APIServerError, APIServerTimedout
-from magicalapi.types.base import ErrorResponse
-
-search_sentence = "movie trailers"
-country = "1"
-language = "1000"
-output_file_name = f"youtube_top_keywords_{search_sentence}.json"
-
-
-async def main():
- try:
- # the api_key will load from the .env file
- async with AsyncClient() as client:
- # get languages and countries list
- # languages = await client.youtube_top_keywords.get_languages()
- # countries = await client.youtube_top_keywords.get_countries()
- # print("Languauges :")
- # print(languages)
- # print("Countries : ")
- # print(countries)
-
- # get youtube keywords
- response = await client.youtube_top_keywords.get_keywords(
- search_sentence=search_sentence,
- country=country,
- language=language,
- )
- if isinstance(response, ErrorResponse):
- # got error from api
- print("Error :", response.message)
- else:
- # got response successfully
- print("credists :", response.usage.credits)
- print("keywords count :", len(response.data.keywords))
-
- # save response in json file
- with open(output_file_name, "w") as file:
- file.write(response.model_dump_json(indent=3))
-
- print(f"response saved to {output_file_name}")
- except (APIServerError, APIServerTimedout) as e:
- # handling server errors
- print(e)
- except Exception as e:
- print("An error occurred:", str(e))
-
-
-asyncio.run(main())
diff --git a/magicalapi/client.py b/magicalapi/client.py
index 17e483e..51e9bfc 100644
--- a/magicalapi/client.py
+++ b/magicalapi/client.py
@@ -7,9 +7,6 @@
ProfileDataService,
ResumeParserService,
ResumeScoreService,
- YoutubeSeoService,
- YoutubeSuggestionsService,
- YoutubeTopKeywordsService,
)
from magicalapi.services.resume_review_service import ResumeReviewService
from magicalapi.settings import settings
@@ -58,18 +55,11 @@ def __init__(self, api_key: str | None = None) -> None:
logger.debug("httpx client created")
# create service
- self.youtube_top_keywords = YoutubeTopKeywordsService(
- httpx_client=self._httpx_client
- )
self.profile_data = ProfileDataService(httpx_client=self._httpx_client)
self.company_data = CompanyDataService(httpx_client=self._httpx_client)
- self.youtube_seo = YoutubeSeoService(httpx_client=self._httpx_client)
self.resume_parser = ResumeParserService(httpx_client=self._httpx_client)
self.resume_score = ResumeScoreService(httpx_client=self._httpx_client)
self.resume_review = ResumeReviewService(httpx_client=self._httpx_client)
- self.youtube_suggestions = YoutubeSuggestionsService(
- httpx_client=self._httpx_client
- )
logger.debug(f"async client created : {self}")
diff --git a/magicalapi/services/__init__.py b/magicalapi/services/__init__.py
index 5fa92f1..1423750 100644
--- a/magicalapi/services/__init__.py
+++ b/magicalapi/services/__init__.py
@@ -3,17 +3,11 @@
from .resume_parser_service import ResumeParserService
from .resume_review_service import ResumeReviewService
from .resume_score_service import ResumeScoreService
-from .youtube_seo_service import YoutubeSeoService
-from .youtube_suggestions_service import YoutubeSuggestionsService
-from .youtube_top_keywords_service import YoutubeTopKeywordsService
__all__ = [
- "YoutubeTopKeywordsService",
"ProfileDataService",
"CompanyDataService",
- "YoutubeSeoService",
"ResumeParserService",
"ResumeScoreService",
"ResumeReviewService",
- "YoutubeSuggestionsService",
]
diff --git a/magicalapi/services/youtube_seo_service.py b/magicalapi/services/youtube_seo_service.py
deleted file mode 100644
index 43972a1..0000000
--- a/magicalapi/services/youtube_seo_service.py
+++ /dev/null
@@ -1,36 +0,0 @@
-"""
-this file stores the implementation of youtube seo Service.
-
-"""
-
-from pydantic import BaseModel
-
-from magicalapi.types.base import ErrorResponse
-from magicalapi.types.schemas import HttpResponse
-from magicalapi.types.youtube_seo import YoutubeSeoResponse
-
-from .base_service import BaseService
-
-
-class YoutubeSeoService(BaseService):
- service_path = "youtube-seo"
-
- async def get_youtube_seo(self, url: str) -> YoutubeSeoResponse | ErrorResponse:
- """this method sends request to youtube seo service in magicalAPI.
-
- url (``str``):
- the URL of youtube video that you want to get it's seo data.
-
- """
- request_body = {
- "video_url": url,
- }
- response = await self._send_post_request(self.service_path, data=request_body)
- return self.validate_response(
- response=response, validate_model=YoutubeSeoResponse
- )
-
- def validate_response(
- self, response: HttpResponse, validate_model: type[BaseModel]
- ) -> YoutubeSeoResponse | ErrorResponse:
- return super().validate_response(response, validate_model)
diff --git a/magicalapi/services/youtube_suggestions_service.py b/magicalapi/services/youtube_suggestions_service.py
deleted file mode 100644
index 16b57bb..0000000
--- a/magicalapi/services/youtube_suggestions_service.py
+++ /dev/null
@@ -1,53 +0,0 @@
-"""
-this file stores the implementation of youtube suggestions Service.
-https://magicalapi.com/services/youtube-suggestions
-
-"""
-
-from typing import Literal
-
-from pydantic import BaseModel
-
-from magicalapi.types.base import ErrorResponse
-from magicalapi.types.schemas import HttpResponse
-from magicalapi.types.youtube_suggestions import YoutubeSuggestionsResponse
-
-from .base_service import BaseService
-
-
-class YoutubeSuggestionsService(BaseService):
- service_path = "youtube-suggestions"
-
- async def get_youtube_suggestions(
- self,
- prompt_sentence: str,
- count: int,
- suggestion_goal: Literal["caption", "title", "hashtag", "tag"],
- ) -> YoutubeSuggestionsResponse | ErrorResponse:
- """this method sends request to youtube suggestions service in magicalAPI.
- https://magicalapi.com/services/youtube-suggestions
-
- prompt_sentence (``str``):
- your prompt sentence to get suggestions based on it
-
- count (``int``)
- the number of results
-
- suggestion_goal (``str``):
- the goal that you want to get suggestions about it, one of `caption`, `title`, `hashtag`, `tag`
-
- """
- request_body = {
- "prompt_sentence": prompt_sentence,
- "count": count,
- "suggestion_goal": suggestion_goal,
- }
- response = await self._send_post_request(self.service_path, data=request_body)
- return self.validate_response(
- response=response, validate_model=YoutubeSuggestionsResponse
- )
-
- def validate_response(
- self, response: HttpResponse, validate_model: type[BaseModel]
- ) -> YoutubeSuggestionsResponse | ErrorResponse:
- return super().validate_response(response, validate_model)
diff --git a/magicalapi/services/youtube_top_keywords_service.py b/magicalapi/services/youtube_top_keywords_service.py
deleted file mode 100644
index 39e610f..0000000
--- a/magicalapi/services/youtube_top_keywords_service.py
+++ /dev/null
@@ -1,115 +0,0 @@
-"""
-this file stores the implementation of Youtube Top Keywords Service.
-https://magicalapi.com/services/youtube-keywords
-
-"""
-
-from typing import overload
-
-from pydantic import BaseModel
-
-from magicalapi.types.base import ErrorResponse
-from magicalapi.types.company_data import CountriesResponse, LanguagesResponse
-from magicalapi.types.schemas import HttpResponse
-from magicalapi.types.youtube_top_keywords import YoutubeTopKeywordsResponse
-
-from .base_service import BaseService
-
-
-class YoutubeTopKeywordsService(BaseService):
- service_path = "youtube-keywords"
-
- @overload
- def validate_response(
- self,
- response: HttpResponse,
- validate_model: type[YoutubeTopKeywordsResponse],
- ) -> YoutubeTopKeywordsResponse | ErrorResponse:
- pass
-
- @overload
- def validate_response(
- self,
- response: HttpResponse,
- validate_model: type[CountriesResponse],
- ) -> CountriesResponse | ErrorResponse:
- pass
-
- @overload
- def validate_response(
- self,
- response: HttpResponse,
- validate_model: type[LanguagesResponse],
- ) -> LanguagesResponse | ErrorResponse:
- pass
-
- @overload
- def validate_response(
- self, response: HttpResponse, validate_model: type[BaseModel]
- ) -> (
- YoutubeTopKeywordsResponse
- | LanguagesResponse
- | CountriesResponse
- | ErrorResponse
- ):
- pass
-
- def validate_response(
- self, response: HttpResponse, validate_model: type[BaseModel]
- ) -> (
- YoutubeTopKeywordsResponse
- | LanguagesResponse
- | CountriesResponse
- | ErrorResponse
- ):
- return super().validate_response(response, validate_model)
-
- async def get_keywords(
- self, search_sentence: str, country: str, language: str
- ) -> YoutubeTopKeywordsResponse | ErrorResponse:
- """this method sends request to Youtube Top Keywords service in magicalAPI.
- https://magicalapi.com/services/youtube-keywords
-
- country (``str``):
- the country code of the country that you want to get keywords from.
-
- language (``str``):
- the language code of the language that you want to get keywords from.
-
- request_id (``str``, *optional*):
- the request_id if you have sent a request before and want to get response of it.
- """
- request_body = {
- "search_sentence": search_sentence,
- "country": country,
- "language": language,
- }
-
- response = await self._send_post_request("/youtube-keywords", data=request_body)
- return self.validate_response(
- response=response, validate_model=YoutubeTopKeywordsResponse
- )
-
- async def get_countries(self) -> CountriesResponse | ErrorResponse:
- """this method retrives the supported
- countries list for Youtube Top Keywords service in magicalAPI.
- https://magicalapi.com/services/youtube-keywords
-
- """
- # get request
- response = await self._send_get_request(self.service_path + "/countries")
- return self.validate_response(
- response=response, validate_model=CountriesResponse
- )
-
- async def get_languages(self) -> LanguagesResponse | ErrorResponse:
- """this method retrives the supported
- languages list for Youtube Top Keywords service in magicalAPI.
- https://magicalapi.com/services/youtube-keywords
-
- """
- # get request
- response = await self._send_get_request(self.service_path + "/languages")
- return self.validate_response(
- response=response, validate_model=LanguagesResponse
- )
diff --git a/magicalapi/types/__init__.py b/magicalapi/types/__init__.py
index 04c3a8b..5c3a051 100644
--- a/magicalapi/types/__init__.py
+++ b/magicalapi/types/__init__.py
@@ -1,11 +1,8 @@
from .base import ErrorResponse
from .profile_data import Profile, ProfileDataResponse
-from .youtube_top_keywords import KeywordIdea, YoutubeTopKeywordsResponse
__all__ = [
"ErrorResponse",
- "YoutubeTopKeywordsResponse",
- "KeywordIdea",
"ProfileDataResponse",
"Profile",
]
diff --git a/magicalapi/types/resume_review.py b/magicalapi/types/resume_review.py
index fbbc9bf..338dd61 100644
--- a/magicalapi/types/resume_review.py
+++ b/magicalapi/types/resume_review.py
@@ -1,5 +1,5 @@
"""
-types schem of youtube seo service
+types schem of resume review service
"""
diff --git a/magicalapi/types/youtube_seo.py b/magicalapi/types/youtube_seo.py
deleted file mode 100644
index 79b2c12..0000000
--- a/magicalapi/types/youtube_seo.py
+++ /dev/null
@@ -1,103 +0,0 @@
-"""
-types schem of youtube seo service
-
-"""
-
-from __future__ import annotations
-
-from datetime import datetime
-from typing import Literal
-
-from pydantic import BaseModel, HttpUrl
-
-from magicalapi.types.base import BaseResponse
-
-
-class YoutubeAPI:
- # youtube api video response schema
-
- class Thumbnail(BaseModel):
- url: HttpUrl
- width: int
- height: int
-
- class Thumbnails(BaseModel):
- default: YoutubeAPI.Thumbnail
- medium: YoutubeAPI.Thumbnail
- high: YoutubeAPI.Thumbnail
- standard: YoutubeAPI.Thumbnail | None = None
- maxres: YoutubeAPI.Thumbnail | None = None
-
- class Localized(BaseModel):
- title: str
- description: str
-
- class Snippet(BaseModel):
- publishedAt: datetime
- channelId: str
- title: str
- description: str
- thumbnails: YoutubeAPI.Thumbnails
- channelTitle: str
- categoryId: str
- liveBroadcastContent: str
- defaultLanguage: str | None = None
- defaultAudioLanguage: str | None = None
- tags: list[str]
-
- class contentDetails(BaseModel):
- duration: str
- definition: Literal["hd", "sd"]
- # TODO ensure empty always
- # contentRating:
-
- class statistics(BaseModel):
- viewCount: int
- likeCount: int
- favoriteCount: int
- commentCount: int | None
-
- class VideoItem(BaseModel):
- kind: str
- etag: str
- id: str
- snippet: YoutubeAPI.Snippet
- contentDetails: YoutubeAPI.contentDetails
- statistics: YoutubeAPI.statistics
-
- class VideoDetails(BaseModel):
- kind: str
- etag: str
- # TODO keep only the first item video
- items: list[YoutubeAPI.VideoItem]
-
-
-class SeoItem(BaseModel):
- pros: list[str]
- cons: list[str]
-
-
-class SeoItems(BaseModel):
- title: SeoItem
- description: SeoItem
- tags: SeoItem
- video_quality: SeoItem
- comments: SeoItem
-
-
-class LongVideoSeoItems(SeoItems):
- thumbnail: SeoItem
-
-
-class ShortVideoSeoItems(SeoItems):
- pass
-
-
-class YoutubeSeo(BaseModel):
- score: int
- result: LongVideoSeoItems | ShortVideoSeoItems
- details: YoutubeAPI.VideoDetails
-
-
-class YoutubeSeoResponse(BaseResponse):
- data: YoutubeSeo
diff --git a/magicalapi/types/youtube_suggestions.py b/magicalapi/types/youtube_suggestions.py
deleted file mode 100644
index 2ff6d7a..0000000
--- a/magicalapi/types/youtube_suggestions.py
+++ /dev/null
@@ -1,33 +0,0 @@
-"""
-types schem of resume score service
-https://magicalapi.com/services/resume-score
-"""
-
-from __future__ import annotations
-
-from .base import BaseModelValidated, BaseResponse
-
-
-class Captions(BaseModelValidated):
- captions: list[str]
-
-
-class Titles(BaseModelValidated):
- titles: list[str]
-
-
-class Hashtags(BaseModelValidated):
- hashtags: list[str]
-
-
-class Keywords(BaseModelValidated):
- keywords: list[str]
-
-
-class YoutubeSuggestionsResponse(BaseResponse):
- """
- the main resposne schema for resume score service
- https://magicalapi.com/services/resume-score
- """
-
- data: Captions | Titles | Hashtags | Keywords
diff --git a/magicalapi/types/youtube_top_keywords.py b/magicalapi/types/youtube_top_keywords.py
deleted file mode 100644
index 830338c..0000000
--- a/magicalapi/types/youtube_top_keywords.py
+++ /dev/null
@@ -1,30 +0,0 @@
-from pydantic import BaseModel
-
-from .base import BaseResponse
-
-
-class KeywordIdeaMonth(BaseModel):
- month: str
- year: int
- monthly_searches: int
-
-
-class KeywordIdea(BaseModel):
- keyword: str
- search_volume: int
- competition: str
- competition_index: int
- low_top_of_page_bid_micros: int
- high_top_of_page_bid_micros: int
- average_cpc: str
- monthly_search: list[KeywordIdeaMonth]
-
-
-class Keywords(BaseModel):
- keywords: list[KeywordIdea]
-
-
-class YoutubeTopKeywordsResponse(BaseResponse):
- """respone model of profile data service"""
-
- data: Keywords
diff --git a/pyproject.toml b/pyproject.toml
index a3512d8..23a219a 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "magicalapi"
-version = "1.1.1"
+version = "1.2.0"
description = "This is a Python client that provides easy access to the MagicalAPI.com services, fully type annotated, and asynchronous."
authors = [
{ name = "MagicalAPI", email = "info@magicalapi.com" }
@@ -64,6 +64,9 @@ allow-direct-references = true
[tool.hatch.build.targets.wheel]
packages = ["magicalapi"]
+[tool.rye.scripts]
+smoke = { cmd = "pytest -vs smoke", env-file = ".env"}
+test = { cmd = "pytest -vs tests"}
[tool.pytest.ini_options]
diff --git a/smoke/test_smoke.py b/smoke/test_smoke.py
index c9150c2..91eaf48 100644
--- a/smoke/test_smoke.py
+++ b/smoke/test_smoke.py
@@ -17,9 +17,6 @@
from magicalapi.types.resume_parser import ResumeParserResponse
from magicalapi.types.resume_review import ResumeReviewResponse
from magicalapi.types.resume_score import ResumeScoreResponse
-from magicalapi.types.youtube_seo import YoutubeSeoResponse
-from magicalapi.types.youtube_suggestions import YoutubeSuggestionsResponse
-from magicalapi.types.youtube_top_keywords import YoutubeTopKeywordsResponse
@pytest_asyncio.fixture(scope="function")
@@ -100,35 +97,3 @@ async def test_resume_score(client: AsyncClient):
)
assert isinstance(response, ResumeScoreResponse)
-
-
-@pytest.mark.asyncio
-async def test_youtube_seo(client: AsyncClient):
- # test api returns 200 and correct response schema
- response = await client.youtube_seo.get_youtube_seo(
- url="https://www.youtube.com/watch?v=PZZI1QXlM80"
- )
-
- assert isinstance(response, YoutubeSeoResponse)
-
-
-@pytest.mark.asyncio
-async def test_youtube_suggestions(client: AsyncClient):
- # test api returns 200 and correct response schema
- response = await client.youtube_suggestions.get_youtube_suggestions(
- prompt_sentence="How to create a profitable Shopify store",
- count=5,
- suggestion_goal="hashtag",
- )
-
- assert isinstance(response, YoutubeSuggestionsResponse)
-
-
-@pytest.mark.asyncio
-async def test_youtube_keywords(client: AsyncClient):
- # test api returns 200 and correct response schema
- response = await client.youtube_top_keywords.get_keywords(
- search_sentence="movie trailers", country="1", language="1000"
- )
-
- assert isinstance(response, YoutubeTopKeywordsResponse)
diff --git a/tests/conftest.py b/tests/conftest.py
index 3581b6a..5514a01 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -8,46 +8,6 @@
Faker.seed()
-@pytest.fixture(scope="function")
-def youtube_keyword():
- # create a sample profile data dictionary
- fake = Faker(locale="en")
- MONTH_LIST = [
- "JANUARY",
- "FEBRUARY",
- "MARCH",
- "APRIL",
- "MAY",
- "JUNE",
- "JULY",
- "AUGUST",
- "SEPTEMBER",
- "OCTOBER",
- "NOVEMBER",
- "DECEMBER",
- ]
- keyword = {
- "keyword": fake.text(max_nb_chars=15),
- "search_volume": randint(1000, 1000000),
- "competition": choice(("LOW", "MEDIUM", "HIGH")),
- "competition_index": randint(0, 100),
- "low_top_of_page_bid_micros": randint(0, 10**7),
- "high_top_of_page_bid_micros": randint(0, 10**7),
- "average_cpc": f"${random.random()}",
- "monthly_search": [
- {
- "month": month,
- "year": randint(2000, 2023),
- "monthly_searches": randint(1000, 1000000),
- }
- for month in MONTH_LIST
- ],
- }
-
- yield keyword
- del keyword
-
-
@pytest.fixture(scope="function")
def resume_data():
# sample data of resume parser service
diff --git a/tests/services/test_base_service.py b/tests/services/test_base_service.py
index 9c16ba4..1ee8d81 100644
--- a/tests/services/test_base_service.py
+++ b/tests/services/test_base_service.py
@@ -8,11 +8,8 @@
from magicalapi.errors import APIServerError, APIServerTimedout
from magicalapi.services.base_service import BaseService
from magicalapi.types.base import ErrorResponse
+from magicalapi.types.resume_score import ResumeScore, ResumeScoreResponse
from magicalapi.types.schemas import HttpResponse
-from magicalapi.types.youtube_top_keywords import (
- KeywordIdea,
- YoutubeTopKeywordsResponse,
-)
@pytest_asyncio.fixture(scope="function")
@@ -68,38 +65,32 @@ async def test_base_service_request_timed_out(httpxclient: httpx.AsyncClient):
await base_service._send_get_request(path="https://httpbin.org/delay/6")
-def test_base_service_validating_response(
- httpxclient: httpx.AsyncClient, youtube_keyword: KeywordIdea
-):
+def test_base_service_validating_response(httpxclient: httpx.AsyncClient):
# test validating base service valida_response method
base_service = BaseService(httpxclient)
# fake response
fake_json_response = {
- "data": {"keywords": [youtube_keyword]},
+ "data": {"score": 10, "reason": "some reason"},
"usage": {"credits": randint(1, 200)},
}
- # test validating youtube top keywords validation
+ # test validating resume score keywords validation
# 200 response
fake_response = HttpResponse(text=json.dumps(fake_json_response), status_code=200)
- assert (
- type(
- base_service.validate_response(
- response=fake_response, validate_model=YoutubeTopKeywordsResponse
- )
- )
- == YoutubeTopKeywordsResponse
+ assert isinstance(
+ base_service.validate_response(
+ response=fake_response, validate_model=ResumeScoreResponse
+ ),
+ ResumeScoreResponse,
)
# 404 response
fake_json_response = {"usage": {"credits": 0}, "message": "request not found !"}
fake_response = HttpResponse(text=json.dumps(fake_json_response), status_code=404)
- assert (
- type(
- base_service.validate_response(
- response=fake_response, validate_model=YoutubeTopKeywordsResponse
- )
- )
- == ErrorResponse
+ assert isinstance(
+ base_service.validate_response(
+ response=fake_response, validate_model=ResumeScoreResponse
+ ),
+ ErrorResponse,
)
@@ -110,5 +101,5 @@ def test_base_service_validating_response_raise_error(httpxclient: httpx.AsyncCl
fake_response = HttpResponse(text="Internal Server Error!", status_code=500)
with pytest.raises(APIServerError):
base_service.validate_response(
- response=fake_response, validate_model=YoutubeTopKeywordsResponse
+ response=fake_response, validate_model=ResumeScoreResponse
)
diff --git a/tests/types/test_youtube_seo_type.py b/tests/types/test_youtube_seo_type.py
deleted file mode 100644
index 2acc48b..0000000
--- a/tests/types/test_youtube_seo_type.py
+++ /dev/null
@@ -1,139 +0,0 @@
-from random import choice, randint
-from uuid import uuid4
-
-import pytest
-from faker import Faker
-from pydantic import ValidationError
-
-from magicalapi.types.youtube_seo import YoutubeSeoResponse
-
-Faker.seed()
-
-
-@pytest.fixture(scope="function")
-def youtube_seo_data(): # type: ignore
- # test data for youtube seo
- fake = Faker(locale="en")
- _video_id = str(uuid4())
- youtube_seo = { # type: ignore
- "score": 41,
- "result": {
- "title": {
- "pros": [],
- "cons": [fake.text()],
- },
- "description": {
- "pros": [],
- "cons": [fake.text(), fake.text(), fake.text()],
- },
- "tags": {
- "pros": [],
- "cons": [fake.text()],
- },
- "comments": {
- "pros": [],
- "cons": [fake.text()],
- },
- "video_quality": {
- "pros": [
- fake.text(),
- ],
- "cons": [],
- },
- "thumbnail": {
- "pros": [fake.text()],
- "cons": [],
- },
- },
- "details": {
- "kind": "youtube#videoListResponse",
- "etag": "dKkUgpwMfKcMUUXnKYiyXvsCcAA",
- "items": [
- {
- "kind": "youtube#video",
- "etag": str(uuid4()),
- "id": _video_id,
- "snippet": {
- "publishedAt": fake.date_time_this_year().strftime("%FT%TZ"),
- "channelId": str(uuid4()),
- "title": fake.text(max_nb_chars=100),
- "description": fake.text(),
- "thumbnails": {
- "default": {
- "url": f"https://i.ytimg.com/vi/{_video_id}/mqdefault.jpg",
- "width": 120,
- "height": 90,
- },
- "medium": {
- "url": f"https://i.ytimg.com/vi/{_video_id}/mqdefault.jpg",
- "width": 320,
- "height": 180,
- },
- "high": {
- "url": f"https://i.ytimg.com/vi/{_video_id}/hqdefault.jpg",
- "width": 480,
- "height": 360,
- },
- },
- "channelTitle": fake.name(),
- "categoryId": str(randint(1, 40)),
- "liveBroadcastContent": "none",
- "defaultLanguage": "en",
- "localized": {
- "title": fake.text(max_nb_chars=100),
- "description": fake.text(),
- },
- "defaultAudioLanguage": "en",
- "tags": [fake.text(max_nb_chars=10) for _ in range(1, 5)],
- },
- "contentDetails": {
- "duration": f"PT{randint(0,59)}M{randint(0,59)}S",
- "dimension": "2d",
- "definition": choice(("hd", "sd")),
- "caption": choice(("true", "false")),
- "licensedContent": choice((True, False)),
- "projection": "rectangular",
- },
- "status": {
- "uploadStatus": "processed",
- "privacyStatus": "public",
- "license": "youtube",
- "embeddable": choice((True, False)),
- "publicStatsViewable": choice((True, False)),
- "madeForKids": choice((True, False)),
- },
- "statistics": {
- "viewCount": str(randint(1, 1000000)),
- "likeCount": str(randint(1, 1000000)),
- "favoriteCount": str(randint(1, 1000000)),
- # "commentCount": str(randint(1, 1000000)),
- "commentCount": None, # test no comment count
- },
- }
- ],
- "pageInfo": {"totalResults": 1, "resultsPerPage": 1},
- },
- }
-
- yield youtube_seo
-
- del youtube_seo
-
-
-def test_youtube_seo_validate_type(youtube_seo_data):
- # test validating youtube_seo response type
- response = {"data": youtube_seo_data, "usage": {"credits": randint(10, 500)}}
-
- assert type(YoutubeSeoResponse.model_validate(response)) == YoutubeSeoResponse
-
-
-def test_youtube_seo_validate_type_failing(youtube_seo_data):
- # test validating youtube_seo response type must fail
- # make data schema invalid
- del youtube_seo_data["score"]
- youtube_seo_data["details"]["items"] = {}
-
- response = {"data": youtube_seo_data, "usage": {"credits": randint(10, 500)}}
-
- with pytest.raises(ValidationError):
- YoutubeSeoResponse.model_validate(response)
diff --git a/tests/types/test_youtube_suggestions_type.py b/tests/types/test_youtube_suggestions_type.py
deleted file mode 100644
index d030e85..0000000
--- a/tests/types/test_youtube_suggestions_type.py
+++ /dev/null
@@ -1,68 +0,0 @@
-from random import randint
-
-import pytest
-from faker import Faker
-
-from magicalapi.types.youtube_suggestions import YoutubeSuggestionsResponse
-
-Faker.seed()
-
-
-@pytest.fixture(scope="function")
-def captions():
- fake = Faker(locale="en")
- captions = {"captions": [fake.text() for _ in range(5)]}
-
- yield captions
-
- del captions
-
-
-@pytest.fixture(scope="function")
-def titles():
- fake = Faker(locale="en")
- titles = {"titles": [fake.text(max_nb_chars=80) for _ in range(5)]}
-
- yield titles
-
- del titles
-
-
-@pytest.fixture(scope="function")
-def hashtags():
- fake = Faker(locale="en")
- hashtags = {"hashtags": [fake.text(max_nb_chars=10) for _ in range(5)]}
-
- yield hashtags
-
- del hashtags
-
-
-@pytest.fixture(scope="function")
-def keywords():
- fake = Faker(locale="en")
- keywords = {"keywords": [fake.text(max_nb_chars=10) for _ in range(5)]}
-
- yield keywords
-
- del keywords
-
-
-def test_youtube_suggestions_validate_type(captions, titles, hashtags, keywords):
- # test validating youtube_suggestions response type
-
- responses = (
- {"data": captions, "usage": {"credits": randint(10, 500)}},
- {"data": titles, "usage": {"credits": randint(10, 500)}},
- {"data": hashtags, "usage": {"credits": randint(10, 500)}},
- {"data": keywords, "usage": {"credits": randint(10, 500)}},
- )
-
- # check all suggestion goals
- assert all(
- [
- type(YoutubeSuggestionsResponse.model_validate(response))
- == YoutubeSuggestionsResponse
- for response in responses
- ]
- )
diff --git a/tests/types/test_youtube_top_keywords_types.py b/tests/types/test_youtube_top_keywords_types.py
deleted file mode 100644
index 8ae3862..0000000
--- a/tests/types/test_youtube_top_keywords_types.py
+++ /dev/null
@@ -1,33 +0,0 @@
-from random import randint
-
-import pytest
-from pydantic import ValidationError
-
-from magicalapi.types.youtube_top_keywords import (
- KeywordIdea,
- YoutubeTopKeywordsResponse,
-)
-
-
-@pytest.mark.dependency()
-def test_youtube_top_keywords_type(youtube_keyword: KeywordIdea):
- try:
- # validating keywords
- KeywordIdea.model_validate(
- obj=youtube_keyword,
- )
-
- except ValidationError as exc:
- assert False, "validating youtube_top_keywords type failed : " + str(exc)
-
-
-@pytest.mark.dependency(depends=["test_youtube_top_keywords_type"])
-def test_youtube_top_keywords_response_type(youtube_keyword: KeywordIdea):
- try:
- response_schema = {
- "data": {"keywords": [youtube_keyword]},
- "usage": {"credits": randint(1, 200)},
- }
- YoutubeTopKeywordsResponse.model_validate(response_schema)
- except ValidationError as exc:
- assert False, "validating youtube_top_keywords response failed : " + str(exc)