qodev-apollo-api 0.2.0__tar.gz → 0.2.1__tar.gz

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.
Files changed (26) hide show
  1. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/CHANGELOG.md +5 -0
  2. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/PKG-INFO +1 -1
  3. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/pyproject.toml +1 -1
  4. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/src/qodev_apollo_api/utils.py +14 -9
  5. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/tests/test_utils.py +17 -11
  6. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/uv.lock +1 -1
  7. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/.github/workflows/ci.yml +0 -0
  8. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/.github/workflows/publish.yml +0 -0
  9. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/.gitignore +0 -0
  10. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/.pre-commit-config.yaml +0 -0
  11. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/CLAUDE.md +0 -0
  12. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/LICENSE +0 -0
  13. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/Makefile +0 -0
  14. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/README.md +0 -0
  15. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/src/qodev_apollo_api/__init__.py +0 -0
  16. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/src/qodev_apollo_api/client.py +0 -0
  17. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/src/qodev_apollo_api/exceptions.py +0 -0
  18. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/src/qodev_apollo_api/models.py +0 -0
  19. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/src/qodev_apollo_api/py.typed +0 -0
  20. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/tests/__init__.py +0 -0
  21. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/tests/integration/__init__.py +0 -0
  22. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/tests/integration/validate_all_models.py +0 -0
  23. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/tests/integration/validate_email_task_flow.py +0 -0
  24. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/tests/test_client.py +0 -0
  25. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/tests/test_exceptions.py +0 -0
  26. {qodev_apollo_api-0.2.0 → qodev_apollo_api-0.2.1}/tests/test_models.py +0 -0
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.1] - 2026-07-01
11
+
12
+ ### Fixed
13
+ - `normalize_linkedin_url()` normalized to `https://` and never added `www`, but Apollo stores and **exact-matches** LinkedIn URLs as `http://www.linkedin.com/in/<slug>`. As a result `find_contact_by_linkedin_url()`'s URL tier always missed (silently falling through to name search), and any `search_contacts(linkedin_url=...)` filter built from it returned zero. It now produces Apollo's `http://www` form, so URL lookups actually match.
14
+
10
15
  ## [0.2.0] - 2026-06-02
11
16
 
12
17
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qodev-apollo-api
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Async Python client for Apollo.io CRM API
5
5
  Project-URL: Homepage, https://github.com/qodevai/apollo-api
6
6
  Project-URL: Repository, https://github.com/qodevai/apollo-api
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "qodev-apollo-api"
3
- version = "0.2.0"
3
+ version = "0.2.1"
4
4
  description = "Async Python client for Apollo.io CRM API"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -167,20 +167,25 @@ def markdown_to_prosemirror(content: str, title: str | None = None) -> str:
167
167
 
168
168
 
169
169
  def normalize_linkedin_url(url: str) -> str:
170
- """Normalize LinkedIn URL for comparison.
170
+ """Normalize a LinkedIn URL to Apollo's stored, exact-match form.
171
+
172
+ Apollo stores and exact-matches LinkedIn URLs as ``http://www.linkedin.com/in/<slug>``
173
+ — **http** scheme (not https), ``www`` host, no trailing slash, lowercase. Producing
174
+ that exact form is what lets a ``linkedin_url`` search actually match; a ``https://``
175
+ or ``www``-less form silently returns zero results. It also doubles as a stable key for
176
+ comparing two URLs.
171
177
 
172
178
  Args:
173
- url: LinkedIn profile URL
179
+ url: LinkedIn profile URL (any common shape).
174
180
 
175
181
  Returns:
176
- Normalized URL (lowercase, stripped, trailing slash removed)
182
+ The URL as ``http://www.linkedin.com/...`` (or ``""`` for a falsy input).
177
183
  """
178
184
  if not url:
179
185
  return ""
180
186
  url = url.lower().strip().rstrip("/")
181
- # Normalize scheme to https://
182
- if url.startswith("http://"):
183
- url = "https://" + url[7:]
184
- elif not url.startswith("https://"):
185
- url = f"https://{url}"
186
- return url
187
+ # Rebuild to Apollo's stored form: strip the scheme, force the www host, force http.
188
+ url = re.sub(r"^https?://", "", url)
189
+ if url.startswith("linkedin.com/"):
190
+ url = "www." + url
191
+ return f"http://{url}"
@@ -82,32 +82,38 @@ def test_prosemirror_empty_doc():
82
82
 
83
83
 
84
84
  def test_normalize_linkedin_url():
85
- """Test LinkedIn URL normalization."""
86
- # Test basic normalization
85
+ """Normalizes to Apollo's stored, exact-match form: http://www.linkedin.com/..."""
86
+ # https is rewritten to Apollo's http, and www is added
87
87
  assert (
88
88
  normalize_linkedin_url("https://linkedin.com/in/johndoe")
89
- == "https://linkedin.com/in/johndoe"
89
+ == "http://www.linkedin.com/in/johndoe"
90
90
  )
91
91
 
92
- # Test lowercase conversion
92
+ # Lowercase conversion
93
93
  assert (
94
94
  normalize_linkedin_url("HTTPS://LinkedIn.com/in/JohnDoe")
95
- == "https://linkedin.com/in/johndoe"
95
+ == "http://www.linkedin.com/in/johndoe"
96
96
  )
97
97
 
98
- # Test trailing slash removal
98
+ # Trailing slash removal
99
99
  assert (
100
100
  normalize_linkedin_url("https://linkedin.com/in/johndoe/")
101
- == "https://linkedin.com/in/johndoe"
101
+ == "http://www.linkedin.com/in/johndoe"
102
102
  )
103
103
 
104
- # Test protocol addition
105
- assert normalize_linkedin_url("linkedin.com/in/johndoe") == "https://linkedin.com/in/johndoe"
104
+ # Protocol addition
105
+ assert normalize_linkedin_url("linkedin.com/in/johndoe") == "http://www.linkedin.com/in/johndoe"
106
106
 
107
- # Test whitespace handling
107
+ # An already-www URL keeps a single www (no www.www)
108
+ assert (
109
+ normalize_linkedin_url("https://www.linkedin.com/in/johndoe")
110
+ == "http://www.linkedin.com/in/johndoe"
111
+ )
112
+
113
+ # Whitespace handling
108
114
  assert (
109
115
  normalize_linkedin_url(" https://linkedin.com/in/johndoe ")
110
- == "https://linkedin.com/in/johndoe"
116
+ == "http://www.linkedin.com/in/johndoe"
111
117
  )
112
118
 
113
119
 
@@ -407,7 +407,7 @@ wheels = [
407
407
 
408
408
  [[package]]
409
409
  name = "qodev-apollo-api"
410
- version = "0.1.3"
410
+ version = "0.2.1"
411
411
  source = { editable = "." }
412
412
  dependencies = [
413
413
  { name = "httpx" },