resumly 0.1.0__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.
resumly-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Resumly
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
resumly-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,467 @@
1
+ Metadata-Version: 2.4
2
+ Name: resumly
3
+ Version: 0.1.0
4
+ Summary: Official Python SDK for the Resumly API — create ATS-optimized, tailored resumes programmatically.
5
+ Author-email: Resumly <support@resumly.ai>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Resumly
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://resumly.ai
29
+ Project-URL: Documentation, https://resumly.ai/docs/api
30
+ Project-URL: Repository, https://github.com/resumly/resumly-python
31
+ Project-URL: Issues, https://github.com/resumly/resumly-python/issues
32
+ Keywords: resume,ats,job-search,api,sdk,career,cover-letter,interview
33
+ Classifier: Development Status :: 4 - Beta
34
+ Classifier: Intended Audience :: Developers
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Programming Language :: Python :: 3
37
+ Classifier: Programming Language :: Python :: 3.8
38
+ Classifier: Programming Language :: Python :: 3.9
39
+ Classifier: Programming Language :: Python :: 3.10
40
+ Classifier: Programming Language :: Python :: 3.11
41
+ Classifier: Programming Language :: Python :: 3.12
42
+ Classifier: Programming Language :: Python :: 3.13
43
+ Classifier: Topic :: Software Development :: Libraries
44
+ Requires-Python: >=3.8
45
+ Description-Content-Type: text/markdown
46
+ License-File: LICENSE
47
+ Requires-Dist: requests>=2.28
48
+ Requires-Dist: pydantic>=2.0
49
+ Dynamic: license-file
50
+
51
+ # Resumly Python SDK
52
+
53
+ Official Python client for the [Resumly API](https://resumly.ai) — full programmatic access to every Resumly feature.
54
+
55
+ ## Installation
56
+
57
+ ```bash
58
+ pip install resumly
59
+ ```
60
+
61
+ Or install from source:
62
+
63
+ ```bash
64
+ cd sdk/
65
+ pip install -e .
66
+ ```
67
+
68
+ ## Quick Start
69
+
70
+ ```python
71
+ from resumly import ResumlyClient
72
+
73
+ client = ResumlyClient(api_key="rly_your_api_key_here")
74
+
75
+ # Upload your base resume
76
+ client.upload_base_resume("my_resume.pdf")
77
+
78
+ # Create a tailored resume for a job posting
79
+ result = client.create_resume(job_url="https://example.com/jobs/12345")
80
+ job_id = result["job_id"]
81
+
82
+ # Get the final resume
83
+ resume = client.get_resume(job_id)
84
+
85
+ # Download as DOCX
86
+ client.download_resume(resume["resume_file_path"], path="tailored.docx")
87
+
88
+ # Run an ATS check on any resume file
89
+ ats = client.run_ats_check("my_resume.pdf")
90
+ print(ats["report"])
91
+ ```
92
+
93
+ ## Getting Your API Key
94
+
95
+ 1. Log in to [resumly.ai](https://resumly.ai)
96
+ 2. Go to **Settings > API Keys**
97
+ 3. Click **Create New Key** and give it a name
98
+ 4. Copy the key (shown only once)
99
+
100
+ ## Complete API Reference
101
+
102
+ ### Constructor
103
+
104
+ ```python
105
+ ResumlyClient(
106
+ api_key="rly_...",
107
+ base_url="https://api.resumly.ai", # override for local dev
108
+ timeout=180, # seconds
109
+ max_retries=3, # auto-retry on 429
110
+ )
111
+ ```
112
+
113
+ ---
114
+
115
+ ### Base Resume
116
+
117
+ | Method | Description |
118
+ |--------|-------------|
119
+ | `upload_base_resume(file_path)` | Upload a PDF/DOCX as your base resume |
120
+ | `get_base_resume()` | Get the parsed JSON of your base resume |
121
+ | `update_base_resume(resume_data)` | Update base resume with new JSON |
122
+ | `improve_base_resume(comments)` | AI-improve base resume from feedback |
123
+ | `translate_base_resume(target_language)` | Translate base resume |
124
+ | `generate_base_resume_docx(resume_data)` | Generate Word doc from base resume |
125
+ | `freeze_base_resume_element(path, freeze)` | Freeze/unfreeze a resume element |
126
+ | `get_locked_elements()` | Get all locked elements |
127
+
128
+ ### User Profile & Settings
129
+
130
+ | Method | Description |
131
+ |--------|-------------|
132
+ | `get_profile()` | Get user profile |
133
+ | `update_profile(email, **fields)` | Update profile fields |
134
+ | `upload_profile_picture(file_path)` | Upload profile picture |
135
+ | `get_user_settings()` | Get all settings |
136
+ | `update_user_settings(settings)` | Update settings |
137
+ | `reset_style_settings()` | Reset style to defaults |
138
+ | `add_always_show_skill(skill)` | Add to always-show skills |
139
+ | `remove_always_show_skill(skill)` | Remove from always-show skills |
140
+ | `add_never_show_skill(skill)` | Add to never-show skills |
141
+ | `remove_never_show_skill(skill)` | Remove from never-show skills |
142
+
143
+ ### Job Preferences
144
+
145
+ | Method | Description |
146
+ |--------|-------------|
147
+ | `get_job_preferences()` | Get job preferences |
148
+ | `update_job_preferences(preferences)` | Update all preferences |
149
+ | `update_job_preference(key, value)` | Update single preference |
150
+ | `delete_job_preference(key)` | Delete a preference |
151
+
152
+ ### Autofill & Custom Instructions
153
+
154
+ | Method | Description |
155
+ |--------|-------------|
156
+ | `get_autofill_attributes()` | Get autofill attributes |
157
+ | `set_autofill_attributes(attributes)` | Set autofill attributes |
158
+ | `get_custom_instructions()` | Get custom AI instructions |
159
+ | `set_custom_instructions(text)` | Set custom AI instructions |
160
+
161
+ ### Memory
162
+
163
+ | Method | Description |
164
+ |--------|-------------|
165
+ | `get_memory()` | Get all memory points |
166
+ | `clear_memory()` | Clear all memory |
167
+ | `delete_memory_point(index)` | Delete specific memory point |
168
+
169
+ ### Credits & Statistics
170
+
171
+ | Method | Description |
172
+ |--------|-------------|
173
+ | `check_credit(email)` | Check credit balance |
174
+ | `check_subscription(email)` | Check subscription status |
175
+ | `get_statistics(queue_statistics)` | Get user statistics |
176
+ | `get_credit_utilization()` | Credit utilization history |
177
+ | `get_ai_insights()` | AI insights for resume applications |
178
+ | `trigger_ai_insights()` | Recalculate AI insights |
179
+ | `get_ai_insights_jobs()` | AI insights for job database |
180
+ | `trigger_ai_insights_jobs()` | Recalculate job AI insights |
181
+ | `get_application_flow()` | Application flow Sankey data |
182
+ | `get_resume_timeline()` | Resume creation timeline |
183
+ | `get_resume_distribution()` | Resume distribution analytics |
184
+
185
+ ---
186
+
187
+ ### Tailored Resumes
188
+
189
+ | Method | Description |
190
+ |--------|-------------|
191
+ | `create_resume(job_url=..., job_description=..., cover_letter=False, interview_question=False)` | Create tailored resume (auto init+process) |
192
+ | `list_recent_resumes(days, favorites_only, queue_only, page, page_size)` | List recent resumes |
193
+ | `get_resume(job_id)` | Get final resume JSON |
194
+ | `update_resume(job_id, data)` | Update final resume |
195
+ | `get_resume_comparison(job_id)` | Base vs tailored comparison |
196
+ | `get_resume_metadata(job_id)` | Metadata (company, title, etc.) |
197
+ | `get_resume_insights(job_id)` | AI insights for resume |
198
+ | `regenerate_insights(job_id)` | Regenerate insights |
199
+ | `delete_resume(job_id)` | Delete resume |
200
+ | `download_resume(s3_url, path)` | Download DOCX file |
201
+ | `export_resume_pdf(job_id, document_type, path)` | Export as PDF |
202
+ | `regenerate_resume(job_id)` | Regenerate resume |
203
+ | `update_job_info(job_id, **fields)` | Update job info |
204
+
205
+ ### Cover Letter
206
+
207
+ | Method | Description |
208
+ |--------|-------------|
209
+ | `create_cover_letter(job_id)` | Generate cover letter |
210
+ | `get_cover_letter(job_id)` | Get cover letter |
211
+ | `update_cover_letter(job_id, data)` | Update cover letter |
212
+ | `regenerate_cover_letter(job_id)` | Regenerate cover letter |
213
+
214
+ ### Interview Questions
215
+
216
+ | Method | Description |
217
+ |--------|-------------|
218
+ | `create_interview_questions(job_id)` | Generate interview questions |
219
+ | `get_interview_questions(job_id)` | Get interview questions |
220
+ | `check_interview_answer(job_id, question, answer)` | Check an answer |
221
+
222
+ ### Resume Actions
223
+
224
+ | Method | Description |
225
+ |--------|-------------|
226
+ | `rephrase_resume(job_id, text)` | Rephrase content |
227
+ | `translate_resume(job_id, target_language)` | Translate resume |
228
+ | `improve_resume(job_id, user_comment)` | AI-improve resume |
229
+ | `chat_with_resume(job_id, message)` | AI chat editing |
230
+ | `generate_bullet_points(**kwargs)` | Generate bullet points |
231
+ | `rephrase_text(text)` | Rephrase any text |
232
+
233
+ ### Favorites & Queue
234
+
235
+ | Method | Description |
236
+ |--------|-------------|
237
+ | `favorite_resume(job_id)` | Toggle favorite |
238
+ | `unfavorite_resume(job_id)` | Remove favorite |
239
+ | `add_to_queue(job_id)` | Add to queue |
240
+ | `remove_from_queue(job_id)` | Remove from queue |
241
+ | `get_auto_apply_resumes()` | Get auto-apply eligible |
242
+
243
+ ### Public Links (Share)
244
+
245
+ | Method | Description |
246
+ |--------|-------------|
247
+ | `create_public_link(job_id, **settings)` | Create shareable link |
248
+ | `get_public_link(job_id)` | Get link info |
249
+ | `update_public_link(job_id, **settings)` | Update link settings |
250
+ | `delete_public_link(job_id)` | Delete link |
251
+
252
+ ### Company Research
253
+
254
+ | Method | Description |
255
+ |--------|-------------|
256
+ | `research_company(job_id)` | Trigger company research |
257
+ | `get_company_research(job_id)` | Get research results |
258
+
259
+ ### Autofill & Feedback
260
+
261
+ | Method | Description |
262
+ |--------|-------------|
263
+ | `autofill_application(job_id, fields)` | Autofill job application |
264
+ | `submit_autofill_feedback(job_id, feedback)` | Submit autofill feedback |
265
+ | `save_change_summary(job_id, summary)` | Save change summary |
266
+ | `get_change_summaries(job_id)` | Get change summaries |
267
+ | `submit_feedback(job_id, feedback)` | Submit resume feedback |
268
+
269
+ ### Email
270
+
271
+ | Method | Description |
272
+ |--------|-------------|
273
+ | `send_resume_email(job_id, **kwargs)` | Send resume via email |
274
+
275
+ ---
276
+
277
+ ### Batch Operations
278
+
279
+ | Method | Description |
280
+ |--------|-------------|
281
+ | `init_batch(job_urls, job_descriptions)` | Initialize batch |
282
+ | `process_batch(batch_id)` | Start processing |
283
+ | `get_batch(batch_id)` | Get batch status |
284
+ | `list_batches()` | List all batches |
285
+ | `get_batch_resumes(batch_id)` | Get resumes in batch |
286
+
287
+ ---
288
+
289
+ ### Job Search
290
+
291
+ | Method | Description |
292
+ |--------|-------------|
293
+ | `generate_job_search_query()` | Generate query from resume |
294
+ | `generate_and_run_search()` | Generate + run immediately |
295
+ | `run_job_search(query_id)` | Run a search |
296
+ | `get_search_queries()` | List all queries |
297
+ | `create_search_query(query)` | Create query |
298
+ | `update_search_query(query_id, query)` | Update query |
299
+ | `delete_search_query(query_id)` | Delete query |
300
+ | `get_relevant_jobs()` | Get relevant jobs |
301
+ | `get_job_status_stats()` | Status statistics |
302
+ | `get_job(job_id)` | Get job details |
303
+ | `get_related_jobs(job_id)` | Get related jobs |
304
+ | `save_job(job_id, save)` | Save/unsave job |
305
+ | `block_job(job_id, block)` | Block/unblock job |
306
+ | `skip_job(job_id, skip)` | Skip/unskip job |
307
+ | `reset_skipped_jobs()` | Reset all skipped |
308
+ | `embed_base_resume()` | Create resume embeddings |
309
+
310
+ ### Job Search Agents
311
+
312
+ | Method | Description |
313
+ |--------|-------------|
314
+ | `create_search_agent(agent)` | Create agent |
315
+ | `update_search_agent(agent_id, agent)` | Update agent |
316
+ | `get_search_agents()` | List agents |
317
+ | `delete_search_agent(agent_id)` | Delete agent |
318
+ | `parse_and_store_job(raw_text)` | Parse raw job text |
319
+
320
+ ### Job Match
321
+
322
+ | Method | Description |
323
+ |--------|-------------|
324
+ | `get_job_match_score(job_description, job_url)` | Get match score |
325
+
326
+ ---
327
+
328
+ ### Templates
329
+
330
+ | Method | Description |
331
+ |--------|-------------|
332
+ | `list_templates()` | List all template types |
333
+ | `list_standard_templates()` | List standard templates |
334
+ | `get_standard_template(id)` | Get standard template |
335
+ | `list_my_templates()` | List user template instances |
336
+ | `create_base_template(template_id)` | Create base template |
337
+ | `list_base_templates()` | List base templates |
338
+ | `get_base_template(id)` | Get base template |
339
+ | `update_base_template_html(id, html)` | Update template HTML |
340
+ | `reset_base_template(id)` | Reset template |
341
+ | `revise_base_template(id, feedback)` | AI revise template |
342
+ | `delete_base_template(id)` | Delete template |
343
+ | `create_resume_template(job_id, template_id)` | Create for resume |
344
+ | `list_resume_templates(job_id)` | List for resume |
345
+ | `get_resume_template(job_id, id)` | Get for resume |
346
+ | `update_resume_template_html(job_id, id, html)` | Update HTML |
347
+ | `reset_resume_template(job_id, id)` | Reset |
348
+ | `revise_resume_template(job_id, id, feedback)` | AI revise |
349
+ | `delete_resume_template(job_id, id)` | Delete |
350
+ | `render_template(job_id, template_id)` | Render template |
351
+ | `compress_content(job_id)` | Compress to fit |
352
+ | `convert_template_to_pdf(html)` | HTML to PDF |
353
+
354
+ ---
355
+
356
+ ### LinkedIn
357
+
358
+ | Method | Description |
359
+ |--------|-------------|
360
+ | `upload_linkedin_profile(profile_data)` | Upload profile |
361
+ | `optimize_linkedin_profile()` | AI optimization |
362
+ | `get_linkedin_profile()` | Get stored profile |
363
+
364
+ ---
365
+
366
+ ### Free Tools
367
+
368
+ All tools accept a resume file path, process it, and return a report.
369
+
370
+ | Method | Description |
371
+ |--------|-------------|
372
+ | `run_ats_check(file_path)` | ATS compatibility check |
373
+ | `run_resume_roast(file_path)` | Brutally honest roast |
374
+ | `run_career_clock(file_path)` | Career clock analysis |
375
+ | `run_interview_questions_tool(file_path)` | Interview questions |
376
+ | `run_career_personality_test(file_path)` | Personality test |
377
+ | `run_skills_gap_analyzer(file_path)` | Skills gap analysis |
378
+ | `run_readability_test(file_path)` | Readability test |
379
+ | `run_linkedin_profile_generator(file_path)` | LinkedIn generator |
380
+ | `run_buzzword_detector(file_path)` | Buzzword detection |
381
+ | `run_job_search_keywords(file_path)` | Search keywords |
382
+ | `run_networking_copilot(file_path)` | Networking strategy |
383
+
384
+ Each tool also has a `get_*_report(analysis_id)` method to retrieve a previous report.
385
+
386
+ ---
387
+
388
+ ### Personalized Learning
389
+
390
+ | Method | Description |
391
+ |--------|-------------|
392
+ | `create_course(**kwargs)` | Create a course |
393
+ | `list_courses()` | List courses |
394
+ | `get_course(course_id)` | Get course |
395
+ | `revise_slide(course_id, **kwargs)` | Revise a slide |
396
+ | `create_mindmap(course_id)` | Create mindmap |
397
+ | `clarify_course(course_id, message)` | Ask question |
398
+
399
+ ### Website Resume (Portfolio)
400
+
401
+ | Method | Description |
402
+ |--------|-------------|
403
+ | `list_website_styles()` | Available styles |
404
+ | `create_website_resume(**kwargs)` | Generate portfolio |
405
+ | `list_website_resumes()` | List portfolios |
406
+ | `get_website_resume(id)` | Get portfolio |
407
+ | `regenerate_website_resume(id, style_id)` | New style |
408
+ | `revise_website_resume(id, feedback)` | AI revise |
409
+ | `reset_website_resume(id)` | Reset to original |
410
+ | `update_website_resume_html(id, html)` | Save HTML |
411
+ | `delete_website_resume(id)` | Delete |
412
+
413
+ ### Affiliate
414
+
415
+ | Method | Description |
416
+ |--------|-------------|
417
+ | `create_affiliate_code()` | Create code |
418
+ | `get_affiliate_stats()` | Get stats |
419
+ | `get_affiliate_transactions()` | Transaction history |
420
+ | `request_affiliate_payout()` | Request payout |
421
+
422
+ ### Other
423
+
424
+ | Method | Description |
425
+ |--------|-------------|
426
+ | `customer_service_chat(message)` | Chat with support bot |
427
+ | `transcribe_audio(file_path)` | Transcribe audio |
428
+ | `report_bug(**kwargs)` | Report a bug |
429
+ | `get_latest_announcement()` | Latest announcement |
430
+ | `delete_account()` | Delete your account |
431
+
432
+ ---
433
+
434
+ ## Error Handling
435
+
436
+ ```python
437
+ from resumly import ResumlyClient, RateLimitError, InsufficientCreditsError
438
+
439
+ client = ResumlyClient(api_key="rly_...")
440
+
441
+ try:
442
+ resume = client.create_resume(job_url="https://example.com/job")
443
+ except RateLimitError as e:
444
+ print(f"Slow down! Retry after {e.retry_after}s")
445
+ except InsufficientCreditsError:
446
+ print("Out of credits — upgrade your plan")
447
+ ```
448
+
449
+ The client auto-retries on 429 (rate limit) up to `max_retries` times.
450
+
451
+ | Exception | HTTP Code | When |
452
+ |-----------|-----------|------|
453
+ | `AuthenticationError` | 401 | Invalid or missing API key |
454
+ | `InsufficientCreditsError` | 403 | Not enough credits |
455
+ | `NotFoundError` | 404 | Resource not found |
456
+ | `ValidationError` | 422 | Invalid request |
457
+ | `RateLimitError` | 429 | Too many requests |
458
+ | `ResumlyError` | * | Any other error |
459
+
460
+ ## Rate Limits
461
+
462
+ - **60 requests per minute**
463
+ - **1,000 requests per day**
464
+
465
+ ## License
466
+
467
+ MIT