Skip to content

Commit 360bd70

Browse files
authored
Merge pull request #17 from magicalapi/add-new-sections-profile-company
add new sections for company and profile data
2 parents c175a7a + f41a8fa commit 360bd70

File tree

6 files changed

+173
-35
lines changed

6 files changed

+173
-35
lines changed

magicalapi/types/company_data.py

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from datetime import datetime
2+
from datetime import date
23
from typing import TypeAlias
34

45
from pydantic import BaseModel, HttpUrl, field_validator
@@ -17,6 +18,51 @@ class Product(BaseModelValidated):
1718
customers: list[URL]
1819

1920

21+
class Employee(BaseModelValidated):
22+
title: str | None
23+
subtitle: str | None
24+
link: str | None
25+
image_url: URL | None
26+
27+
28+
class SimilarCompany(BaseModelValidated):
29+
title: str | None
30+
subtitle: str | None
31+
location: str | None
32+
link: str | None
33+
34+
35+
class Post(BaseModelValidated):
36+
text: str | None
37+
38+
post_url: URL | None
39+
post_id: str | None
40+
time: str | None
41+
videos: list[str]
42+
images: list[str]
43+
likes_count: int | None
44+
comments_count: int | None
45+
46+
47+
class Investor(BaseModelValidated):
48+
name: str | None
49+
link: str | None
50+
image_url: URL | None
51+
52+
53+
class FundingRound(BaseModelValidated):
54+
date: date | None
55+
type: str | None
56+
raised_amount: str | None
57+
58+
59+
class Funding(BaseModelValidated):
60+
last_round: FundingRound | None
61+
rounds_count: int | None
62+
investors: list[Investor]
63+
crunchbase_url: URL | None
64+
65+
2066
class Company(BaseModelValidated):
2167
"""
2268
The main type of company data service
@@ -41,8 +87,13 @@ class Company(BaseModelValidated):
4187
foundedOn: str | None
4288
specialties: str | None
4389
#
44-
locations: list[list[str]]
4590
products: list[Product]
91+
locations: list[list[str]]
92+
#
93+
employees_at_linkedin: list[Employee]
94+
similar_companies: list[SimilarCompany]
95+
funding: Funding
96+
posts: list[Post]
4697

4798
@field_validator("crawled_at", mode="before")
4899
@classmethod
@@ -52,20 +103,3 @@ def datetime_validator(cls, value: str) -> datetime:
52103

53104
class CompanyDataResponse(BaseResponse):
54105
data: Company
55-
56-
57-
class Language(BaseModel):
58-
name: str
59-
code: str
60-
61-
62-
class Country(Language):
63-
pass
64-
65-
66-
class LanguagesResponse(BaseResponse):
67-
data: list[Language]
68-
69-
70-
class CountriesResponse(BaseResponse):
71-
data: list[Country]

magicalapi/types/profile_data.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
class StartEndDate(BaseModelValidated):
99
# Example: "Jan 2024" or "2024-01" or "Present"
10-
start_date: str | None
11-
end_date: str | None
10+
start_date: int | str | None
11+
end_date: int | str | None
1212

1313
# validating the dates in format %b %Y ,Example : Jan 2024
1414
# @field_validator("start_date", "end_date", mode="before")
@@ -52,7 +52,7 @@ class StartEndDateEducation(StartEndDate):
5252
# raise e
5353

5454

55-
class Duration(BaseModel):
55+
class Duration(BaseModelValidated):
5656
years: int = 0
5757
months: int
5858

@@ -143,6 +143,26 @@ def date_validator(cls, value: str) -> date | None:
143143
return datetime.strptime(value, "%b %Y").date()
144144

145145

146+
class Activity(BaseModelValidated):
147+
title: str | None
148+
subtitle: str | None
149+
image_url: str | None
150+
link: str | None
151+
152+
153+
class SimilarProfile(BaseModelValidated):
154+
url: str | None
155+
name: str | None
156+
title: str | None
157+
image_url: str | None
158+
159+
160+
class Patent(BaseModelValidated):
161+
title: str | None
162+
patent_id: str | None
163+
link: str | None
164+
165+
146166
class Profile(BaseModelValidated):
147167
"""
148168
The main type of linkedin profile data service
@@ -166,6 +186,10 @@ class Profile(BaseModelValidated):
166186
courses: list[Course]
167187
honors_and_awards: list[HonorAndAward]
168188

189+
activities: list[Activity]
190+
similar_profiles: list[SimilarProfile]
191+
patents: list[Patent]
192+
169193
@field_validator("crawled_at", mode="before")
170194
@classmethod
171195
def datetime_validator(cls, value: str) -> datetime:

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "magicalapi"
3-
version = "1.3.0"
3+
version = "1.4.0"
44
description = "This is a Python client that provides easy access to the MagicalAPI.com services, fully type annotated, and asynchronous."
55
authors = [
66
{ name = "MagicalAPI", email = "info@magicalapi.com" }

tests/types/test_company_data_type.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,59 @@ def company_data():
5050
"customers": [fake.uri()],
5151
}
5252
],
53+
#
54+
"employees_at_linkedin": [
55+
{
56+
"title": fake.job(),
57+
"subtitle": fake.text(max_nb_chars=30),
58+
"link": f"https://linkedin.com/in/{fake.user_name()}/",
59+
"image_url": fake.image_url(),
60+
}
61+
for _ in range(randint(1, 5))
62+
],
63+
"similar_companies": [
64+
{
65+
"title": fake.company(),
66+
"subtitle": fake.text(max_nb_chars=50),
67+
"location": fake.city(),
68+
"link": f"https://linkedin.com/company/{fake.slug()}/",
69+
}
70+
for _ in range(randint(1, 3))
71+
],
72+
"funding": {
73+
"last_round": {
74+
"date": fake.date_between(
75+
start_date="-5y", end_date="today"
76+
).isoformat(),
77+
"type": fake.random_element(
78+
elements=("Seed", "Series A", "Series B", "Series C", "IPO")
79+
),
80+
"raised_amount": f"${randint(1, 100)}M",
81+
},
82+
"rounds_count": randint(1, 5),
83+
"investors": [
84+
{
85+
"name": fake.company(),
86+
"link": f"https://linkedin.com/company/{fake.slug()}/",
87+
"image_url": fake.image_url(),
88+
}
89+
for _ in range(randint(1, 4))
90+
],
91+
"crunchbase_url": f"https://crunchbase.com/organization/{fake.slug()}",
92+
},
93+
"posts": [
94+
{
95+
"text": fake.text(max_nb_chars=200),
96+
"post_url": f"https://linkedin.com/posts/{fake.user_name()}_{fake.uuid4()}",
97+
"post_id": fake.uuid4(),
98+
"time": fake.date_time_this_month().strftime("%Y-%m-%d %H:%M:%S"),
99+
"videos": [fake.url() for _ in range(randint(0, 2))],
100+
"images": [fake.image_url() for _ in range(randint(0, 3))],
101+
"likes_count": randint(0, 1000),
102+
"comments_count": randint(0, 100),
103+
}
104+
for _ in range(randint(1, 3))
105+
],
53106
}
54107

55108
yield company

tests/types/test_profile_data_type.py

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414

1515
@pytest.fixture()
16-
def profile_dataprofile_data():
16+
def profile_data():
1717
# create a sample profile data dictionary
1818
fake = Faker(locale="en_US")
1919
_username = fake.user_name()
@@ -188,31 +188,58 @@ def profile_dataprofile_data():
188188
"description": "",
189189
},
190190
],
191+
#
192+
"activities": [
193+
{
194+
"title": fake.text(max_nb_chars=50),
195+
"subtitle": fake.text(max_nb_chars=30),
196+
"image_url": fake.image_url(),
197+
"link": fake.uri(),
198+
}
199+
for _ in range(randint(1, 3))
200+
],
201+
"similar_profiles": [
202+
{
203+
"url": f"https://linkedin.com/in/{fake.user_name()}/",
204+
"name": fake.name(),
205+
"title": fake.job(),
206+
"image_url": fake.image_url(),
207+
}
208+
for _ in range(randint(1, 5))
209+
],
210+
"patents": [
211+
{
212+
"title": fake.text(max_nb_chars=100),
213+
"patent_id": f"US{randint(1000000, 9999999)}",
214+
"link": f"https://patents.google.com/patent/US{randint(1000000, 9999999)}",
215+
}
216+
for _ in range(randint(0, 2))
217+
],
191218
}
192219

193220
yield profile
194221
del profile
195222

196223

197224
@pytest.mark.dependency()
198-
def test_profile_data_type(profile_dataprofile_data: dict[str, Any]):
225+
def test_profile_data_type(profile_data: dict[str, Any]):
199226
# check profile data validated successfull
200227
try:
201-
Profile.model_validate(profile_dataprofile_data)
228+
Profile.model_validate(profile_data)
202229
except ValidationError as exc:
203230
assert False, "validating profile data failed : " + str(exc)
204231

205232

206233
@pytest.mark.dependency()
207-
def test_profile_data_type_failing(profile_dataprofile_data: dict[str, Any]):
234+
def test_profile_data_type_failing(profile_data: dict[str, Any]):
208235
# validating profile data must fail
209-
profile_dataprofile_data["experience"][0]["date"]["start_date"] = "none"
210-
del profile_dataprofile_data["education"][0]["date"]
211-
del profile_dataprofile_data["projects"][0]["date"]["end_date"]
212-
profile_dataprofile_data["publications"][0]["publication_date"] = 12
213-
profile_dataprofile_data["honors_and_awards"][0]["issued_date"] = None
236+
profile_data["experience"][0]["date"]["start_date"] = "none"
237+
del profile_data["education"][0]["date"]
238+
del profile_data["projects"][0]["date"]["end_date"]
239+
profile_data["publications"][0]["publication_date"] = 12
240+
profile_data["honors_and_awards"][0]["issued_date"] = None
214241
try:
215-
Profile.model_validate(profile_dataprofile_data)
242+
Profile.model_validate(profile_data)
216243
except:
217244
pass
218245
else:
@@ -223,10 +250,10 @@ def test_profile_data_type_failing(profile_dataprofile_data: dict[str, Any]):
223250
@pytest.mark.dependency(
224251
depends=["test_profile_data_type", "test_profile_data_type_failing"]
225252
)
226-
def test_profile_data_response_type(profile_dataprofile_data: dict[str, Any]):
253+
def test_profile_data_response_type(profile_data: dict[str, Any]):
227254
try:
228255
response_schema = {
229-
"data": profile_dataprofile_data,
256+
"data": profile_data,
230257
"usage": {"credits": randint(1, 200)},
231258
}
232259
ProfileDataResponse.model_validate(response_schema)

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)