wefunder 0.1.0b0__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.
- wefunder-0.1.0b0/.gitignore +9 -0
- wefunder-0.1.0b0/LICENSE +21 -0
- wefunder-0.1.0b0/PKG-INFO +345 -0
- wefunder-0.1.0b0/README.md +311 -0
- wefunder-0.1.0b0/examples/README.md +15 -0
- wefunder-0.1.0b0/pyproject.toml +81 -0
- wefunder-0.1.0b0/src/wefunder/__init__.py +105 -0
- wefunder-0.1.0b0/src/wefunder/_generated/__init__.py +8 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/activity/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/activity/list_activity.py +310 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/activity/list_connected_apps.py +142 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/activity/revoke_connected_app.py +174 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/attribution/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/attribution/get_attribution_stats.py +304 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/attribution/list_attributed_investments.py +343 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/attribution_partners/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/attribution_partners/create_partner_invite.py +212 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/attribution_partners/get_attribution_me.py +146 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/attribution_partners/list_attribution_campaigns.py +150 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/attribution_partners/list_partner_invites.py +146 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/attribution_partners/register_as_partner.py +183 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/attribution_partners/revoke_partner_invite.py +177 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/attribution_webhooks/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/attribution_webhooks/create_webhook_subscription.py +308 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/attribution_webhooks/delete_webhook_subscription.py +191 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/attribution_webhooks/get_webhook_subscription.py +199 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/attribution_webhooks/list_webhook_subscriptions.py +190 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/attribution_webhooks/reactivate_webhook_subscription.py +210 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/attribution_webhooks/regenerate_webhook_secret.py +205 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/attribution_webhooks/test_webhook_subscription.py +206 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/campaigns/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/campaigns/list_campaigns.py +228 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/companies/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/companies/search_companies.py +242 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/explore/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/explore/get_company.py +246 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/explore/get_company_disclosures.py +267 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/explore/get_company_pitch.py +279 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/explore/get_company_update.py +196 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/explore/get_offering.py +203 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/explore/list_company_questions.py +339 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/explore/list_company_updates.py +238 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/explore/list_offerings.py +484 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/installations/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/installations/create_installation.py +216 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/installations/create_installation_token.py +217 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/installations/get_installation.py +166 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/installations/list_eligible_install_targets.py +188 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/installations/list_installations.py +155 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/installations/revoke_installation.py +183 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/intents/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/intents/create_intent.py +296 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/intents/get_intent.py +176 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/intents/list_intents.py +239 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/intents/preview_intent.py +204 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/investment_delta/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/investment_delta/list_company_investment_changes.py +310 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/investments/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/investments/get_investment.py +198 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/investments/get_offering_stats.py +198 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/investments/list_investments.py +386 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/portfolio/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/portfolio/get_portfolio.py +256 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/portfolio/list_portfolio_positions.py +284 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_deals/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_deals/close_syndicate_deal.py +214 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_deals/finalize_syndicate_deal.py +214 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_deals/get_syndicate_deal.py +193 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_deals/list_syndicate_deal_investors.py +265 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_deals/list_syndicate_deals.py +218 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_members/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_members/approve_syndicate_member.py +192 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_members/demote_syndicate_member.py +188 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_members/export_syndicate_members_csv.py +172 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_members/hide_syndicate_member.py +188 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_members/invite_syndicate_member.py +200 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_members/list_syndicate_member_investments.py +205 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_members/list_syndicate_members.py +354 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_members/promote_syndicate_member.py +188 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_members/remove_syndicate_member.py +181 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_members/reorder_syndicate_members.py +189 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_members/resend_syndicate_invite.py +174 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_members/restore_syndicate_member.py +188 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_members/update_syndicate_member.py +209 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_portfolio/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_portfolio/get_syndicate_portfolio.py +276 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_portfolio/list_syndicate_portfolio_positions.py +291 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_statistics/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicate_statistics/get_syndicate_statistics.py +203 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicates/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicates/get_syndicate.py +183 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicates/list_syndicates.py +198 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/syndicates/update_syndicate.py +204 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/users/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/users/follow_company.py +202 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/users/get_current_user.py +181 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/users/list_followed_companies.py +206 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/users/list_my_companies.py +171 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/users/unfollow_company.py +190 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/webhook_endpoints/__init__.py +1 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/webhook_endpoints/create_webhook_endpoint.py +204 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/webhook_endpoints/delete_webhook_endpoint.py +183 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/webhook_endpoints/get_webhook_endpoint.py +179 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/webhook_endpoints/list_webhook_endpoints.py +151 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/webhook_endpoints/reenable_webhook_endpoint.py +187 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/webhook_endpoints/rotate_webhook_endpoint_secret.py +187 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/webhook_endpoints/test_webhook_endpoint.py +227 -0
- wefunder-0.1.0b0/src/wefunder/_generated/api/webhook_endpoints/update_webhook_endpoint.py +218 -0
- wefunder-0.1.0b0/src/wefunder/_generated/client.py +268 -0
- wefunder-0.1.0b0/src/wefunder/_generated/errors.py +16 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/__init__.py +951 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/anonymized_attribution.py +151 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/anonymized_attribution_amount_tier.py +10 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/anonymized_attribution_attribution.py +175 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/anonymized_attribution_attribution_quality_score.py +11 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/anonymized_attribution_attribution_time_to_invest_bucket.py +10 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/anonymized_attribution_status.py +81 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/anonymized_attribution_status_bucket.py +13 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/attributed_investment_list_envelope.py +126 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/attributed_investment_list_envelope_meta.py +123 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/attributed_investment_list_envelope_meta_detail_level.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/attribution_campaign_access.py +88 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/attribution_campaign_summary.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/attribution_campaign_summary_list_envelope.py +79 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/attribution_me.py +131 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/attribution_me_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/attribution_partner_type_0.py +96 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/attribution_partner_type_0_status.py +10 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/attribution_stats.py +166 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/attribution_stats_by_campaign_item.py +79 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/attribution_stats_by_source_item.py +79 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/attribution_stats_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/attribution_stats_period.py +85 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/attribution_stats_quality_breakdown.py +80 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/attribution_stats_totals.py +88 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/attribution_user.py +79 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/audit_event.py +101 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/audit_event_attributes.py +364 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/audit_event_attributes_new_values_type_0.py +47 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/audit_event_attributes_old_values_type_0.py +47 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/audit_event_attributes_status.py +10 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/audit_event_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/bulk_invite_link_create_input.py +76 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/bulk_invite_link_envelope.py +121 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/bulk_invite_link_envelope_errors_item.py +79 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/bulk_invite_link_envelope_meta.py +79 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/campaign.py +92 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/campaign_attributes.py +211 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/campaign_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/comment_proposal_envelope.py +185 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/comment_proposal_envelope_draft_type_0.py +122 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/comment_proposal_envelope_draft_type_0_params.py +45 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/comment_proposal_envelope_proposal.py +117 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/comment_proposal_envelope_proposal_target_type.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/comment_proposal_envelope_related_questions_item.py +158 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company.py +93 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_attributes.py +275 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_attributes_location.py +113 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_disclosures.py +102 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_disclosures_attributes.py +667 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_disclosures_attributes_business.py +164 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_disclosures_attributes_capital_structure_type_0_item.py +153 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_disclosures_attributes_current_position.py +187 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_disclosures_attributes_filing.py +154 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_disclosures_attributes_financial_statements.py +110 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_disclosures_attributes_outstanding_debts_type_0.py +104 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_disclosures_attributes_outstanding_debts_type_0_items_item.py +164 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_disclosures_attributes_outstanding_notes_type_0_item.py +213 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_disclosures_attributes_prior_offerings_type_0_item.py +184 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_disclosures_attributes_ratios_type_0.py +175 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_disclosures_attributes_related_parties_type_0.py +104 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_disclosures_attributes_related_parties_type_0_parties_item.py +184 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_disclosures_attributes_use_of_funds_type_0_item.py +93 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_disclosures_attributes_voting_power_type_0_item.py +113 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_disclosures_envelope.py +75 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_disclosures_type.py +8 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_pitch.py +101 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_pitch_attributes.py +200 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_pitch_attributes_authored_by.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_pitch_attributes_perks_type_0.py +122 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_pitch_attributes_story.py +117 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_pitch_envelope.py +75 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_pitch_type.py +8 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_question.py +101 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_question_attributes.py +216 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_question_attributes_answers_item.py +143 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_question_attributes_match.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_question_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_question_list_envelope_meta.py +187 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_question_person.py +123 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_question_type.py +8 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_search_result.py +101 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_search_result_attributes.py +158 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_search_result_list_envelope.py +99 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_search_result_list_envelope_meta.py +70 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_search_result_type.py +8 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_totals.py +140 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_update.py +113 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_update_attributes.py +313 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_update_attributes_author_type_0.py +73 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_update_attributes_visibility_type_1.py +12 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_update_attributes_visibility_type_2_type_1.py +12 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_update_attributes_visibility_type_3_type_1.py +12 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_update_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_update_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_update_list_envelope_meta.py +99 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/company_update_type.py +8 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/connected_app.py +93 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/connected_app_attributes.py +145 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/connected_app_list_envelope.py +79 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/connected_app_revocation.py +70 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/connected_app_revocation_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/convertible_note_security.py +100 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/convertible_note_security_terms.py +152 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/convertible_note_security_type.py +8 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/create_installation_body.py +92 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/create_installation_body_target_type.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/create_installation_token_body.py +63 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/create_intent_body.py +124 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/create_intent_body_action_name.py +13 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/create_intent_body_params.py +52 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/create_partner_invite_body.py +91 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/create_partner_invite_body_direction.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/create_webhook_endpoint_body.py +99 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/create_webhook_endpoint_body_events_item.py +28 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/create_webhook_endpoint_body_mode.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/create_webhook_subscription_body.py +80 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/create_webhook_subscription_body_events_item.py +10 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/current_raise.py +184 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/deal_investor.py +95 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/deal_investor_attributes.py +178 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/deal_investor_attributes_status.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/deal_investor_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/deal_investor_list_envelope_meta.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/debt_security.py +100 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/debt_security_terms.py +124 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/debt_security_type.py +8 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/delete_webhook_endpoint_response_200.py +76 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/delete_webhook_endpoint_response_200_data.py +79 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/disclosure_document.py +82 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/disclosure_person.py +131 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/eligible_target_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/eligible_target_list_envelope_data_item.py +143 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/eligible_target_list_envelope_data_item_type.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/eligible_target_list_envelope_meta.py +45 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/equity_security.py +100 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/equity_security_terms.py +168 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/equity_security_terms_share_class_type_1.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/equity_security_terms_share_class_type_2_type_1.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/equity_security_terms_share_class_type_3_type_1.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/equity_security_type.py +8 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/error.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/error_error.py +111 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/error_error_details.py +45 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/exemption.py +106 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/exemption_family.py +13 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/fiscal_year_financials.py +234 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/follow_state_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/follow_state_envelope_data.py +112 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/follow_state_envelope_data_attributes.py +70 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/follow_state_envelope_data_type.py +8 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/followed_company.py +101 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/followed_company_attributes.py +182 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/followed_company_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/followed_company_type.py +8 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/full_attribution.py +157 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/full_attribution_attribution.py +171 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/full_attribution_attribution_quality_score.py +11 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/full_attribution_attribution_time_to_invest_bucket.py +10 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/full_attribution_investor.py +89 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/full_attribution_status.py +78 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/full_attribution_status_bucket.py +13 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/fund_security.py +101 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/fund_security_terms.py +45 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/fund_security_type.py +8 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/get_company_disclosures_sections_item.py +24 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/get_company_pitch_sections_item.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/get_portfolio_status.py +11 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/get_syndicate_portfolio_status.py +11 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/installation.py +92 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/installation_attributes.py +178 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/installation_attributes_status.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/installation_attributes_target.py +87 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/installation_attributes_target_type.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/installation_envelope.py +92 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/installation_envelope_meta.py +45 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/installation_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/installation_list_envelope_meta.py +61 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/installation_token_envelope.py +111 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/installation_token_envelope_meta.py +45 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/installation_token_envelope_token.py +99 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/intent.py +94 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/intent_attributes.py +336 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/intent_attributes_execution_result_type_0.py +47 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/intent_attributes_status.py +14 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/intent_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/intent_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/intent_preview_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/intent_preview_envelope_data.py +93 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/intent_preview_envelope_data_attributes.py +121 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/intent_preview_envelope_data_attributes_params.py +45 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/intent_preview_envelope_data_type.py +8 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/intent_review.py +83 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_change_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_change_list_envelope_meta.py +106 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_change_list_envelope_meta_mode.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_delta_record.py +422 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_delta_record_amounts.py +100 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_delta_record_blockers_item.py +81 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_delta_record_contracts_item.py +102 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_delta_record_investor.py +164 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_delta_record_investor_address.py +47 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_delta_record_reason.py +10 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_delta_record_status.py +12 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_envelope.py +96 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_envelope_meta.py +122 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_envelope_meta_source.py +8 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_list_envelope_meta.py +130 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_list_envelope_meta_mode.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_session.py +92 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_session_attributes.py +278 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_session_attributes_events_item.py +87 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_session_attributes_funding_status.py +11 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_session_attributes_kyc_status.py +10 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_session_attributes_metadata.py +47 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_session_attributes_status.py +13 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_session_create_input.py +246 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_session_create_input_metadata_type_0.py +47 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_session_envelope.py +92 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_session_envelope_meta.py +61 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_session_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investment_session_list_envelope_meta.py +99 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investor.py +94 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investor_attributes.py +148 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investor_envelope.py +75 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/investor_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/invite_link.py +96 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/invite_link_attributes.py +308 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/invite_link_attributes_events_item.py +118 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/invite_link_attributes_status.py +11 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/invite_link_create_input.py +213 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/invite_link_envelope.py +95 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/invite_link_envelope_meta.py +61 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/invite_link_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/invite_link_list_envelope_meta.py +99 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/invite_link_update_input.py +95 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/invite_syndicate_member_body.py +93 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/invite_syndicate_member_body_syndicate_permission.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/list_activity_status.py +10 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/list_attributed_investments_detail_level.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/list_company_questions_sort.py +11 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/list_eligible_install_targets_target_type.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/list_intents_status.py +13 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/list_investments_status.py +12 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/list_offerings_business_model_item.py +15 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/list_offerings_exemption.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/list_offerings_industry_item.py +57 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/list_offerings_security.py +14 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/list_offerings_sort.py +11 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/list_portfolio_positions_status.py +11 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/list_syndicate_members_accredited.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/list_syndicate_members_has_invested.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/list_syndicate_members_permission.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/list_syndicate_members_sort.py +12 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/list_syndicate_portfolio_positions_status.py +11 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/marketing_partner.py +134 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/marketing_partner_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/marketing_partner_status.py +10 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/member_investment.py +94 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/member_investment_attributes.py +148 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/member_investment_attributes_status.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/member_investment_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/member_investment_list_envelope_meta.py +70 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/my_company.py +102 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/my_company_attributes.py +121 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/my_company_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/my_company_list_envelope_meta.py +61 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/my_company_type.py +8 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/offering.py +155 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/offering_attributes.py +633 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/offering_attributes_intended_security_type_0.py +81 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/offering_attributes_intended_security_type_0_type.py +13 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/offering_attributes_status.py +11 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/offering_envelope.py +76 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/offering_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/offering_list_envelope_meta.py +132 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/offering_list_envelope_meta_filters.py +52 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/offering_stats_envelope.py +92 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/offering_stats_envelope_data.py +130 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/offering_stats_envelope_data_by_status.py +64 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/offering_stats_envelope_data_by_status_additional_property.py +79 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/offering_stats_envelope_data_total.py +80 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/offering_stats_envelope_meta.py +100 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/offering_stats_envelope_meta_source.py +8 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/offering_warnings_item.py +79 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/offering_warnings_item_code.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/other_security.py +101 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/other_security_terms.py +113 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/other_security_type.py +8 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/pagination_meta.py +94 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_investment.py +92 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_investment_attributes.py +198 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_investment_attributes_accreditation_type_0.py +141 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_investment_attributes_accreditation_type_0_status.py +11 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_investment_attributes_accreditation_type_0_type.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_investment_attributes_status.py +12 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_investment_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_investment_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_investor.py +94 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_investor_attributes.py +152 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_investor_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_invite.py +217 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_invite_direction.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_invite_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_invite_list_envelope.py +79 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_invite_status.py +11 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_webhook_event.py +139 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_webhook_event_data.py +47 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_webhook_event_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_webhook_subscription.py +94 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_webhook_subscription_attributes.py +98 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_webhook_subscription_create_input.py +69 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_webhook_subscription_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_webhook_subscription_list_envelope.py +79 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_webhook_subscription_with_secret.py +94 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_webhook_subscription_with_secret_attributes.py +63 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/partner_webhook_subscription_with_secret_envelope.py +76 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/past_round.py +215 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/past_round_source.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/perk_tier.py +81 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/pitch_block.py +226 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/pitch_block_links_item.py +82 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/pitch_block_type.py +13 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/portfolio_company_ref.py +91 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/portfolio_holding.py +94 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/portfolio_holding_status.py +10 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/portfolio_position.py +104 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/portfolio_position_attributes.py +388 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/portfolio_position_attributes_asset_type.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/portfolio_position_attributes_exit_reason.py +12 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/portfolio_position_attributes_status.py +11 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/portfolio_position_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/portfolio_position_list_envelope_meta.py +90 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/portfolio_position_type.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/portfolio_security.py +281 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/portfolio_security_owner_type_0.py +82 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/portfolio_security_owner_type_0_kind.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/portfolio_security_terms.py +134 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/portfolio_summary_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/portfolio_summary_envelope_data.py +85 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/portfolio_summary_envelope_data_attributes.py +174 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/portfolio_summary_envelope_data_attributes_position_counts.py +89 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/preview_intent_body.py +101 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/preview_intent_body_params.py +45 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/register_as_partner_body.py +72 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/reorder_syndicate_members_body.py +63 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/revenue_share_security.py +100 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/revenue_share_security_terms.py +223 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/revenue_share_security_terms_revenue_basis_type_1.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/revenue_share_security_terms_revenue_basis_type_2_type_1.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/revenue_share_security_terms_revenue_basis_type_3_type_1.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/revenue_share_security_type.py +8 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/safe_security.py +100 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/safe_security_terms.py +123 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/safe_security_type.py +8 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/security_summary.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/security_summary_type.py +14 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv.py +92 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_attributes.py +290 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_attributes_metadata.py +45 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_attributes_status.py +13 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_attributes_target_company.py +70 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_cancel_intent_envelope.py +93 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_cancel_intent_envelope_meta.py +77 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_close_intent_envelope.py +93 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_close_intent_envelope_meta.py +77 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_create_input.py +124 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_create_input_metadata.py +52 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_metrics.py +107 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_settings.py +89 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_settings_accreditation_type.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_status.py +92 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_status_attributes.py +130 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_status_attributes_status.py +12 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_status_envelope.py +92 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_status_envelope_meta.py +61 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_terms.py +146 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_terms_safe_type.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_terms_structure.py +10 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_with_meta_envelope.py +92 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/spv_with_meta_envelope_meta.py +61 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate.py +93 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_attributes.py +368 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_attributes_annual_subscription.py +114 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_attributes_traditional_fund.py +82 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_deal.py +94 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_deal_attributes.py +542 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_deal_attributes_status.py +11 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_deal_close_intent_envelope.py +95 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_deal_close_intent_envelope_meta.py +77 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_deal_detail_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_deal_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_deal_finalize_intent_envelope.py +95 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_deal_finalize_intent_envelope_meta.py +77 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_deal_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_detail_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_member.py +94 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_member_attributes.py +705 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_member_attributes_syndicate_permission.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_member_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_member_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_portfolio_summary_envelope.py +76 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_portfolio_summary_envelope_data.py +87 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_portfolio_summary_envelope_data_attributes.py +183 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_portfolio_summary_envelope_data_attributes_deal_counts.py +89 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_statistics.py +84 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_statistics_attributes.py +135 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_statistics_attributes_members_by_role.py +52 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/syndicate_statistics_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/tag_ref.py +70 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/target_company_input.py +99 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/test_webhook_endpoint_body.py +70 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/test_webhook_endpoint_body_event.py +28 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/update_syndicate_body.py +67 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/update_syndicate_body_syndicate.py +79 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/update_syndicate_member_body.py +67 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/update_syndicate_member_body_member.py +70 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/update_webhook_endpoint_body.py +83 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/update_webhook_endpoint_body_events_item.py +28 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/user.py +92 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/user_attributes.py +215 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/user_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/validation_error.py +76 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/validation_error_error.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/validation_error_error_details_item.py +79 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_delivery.py +182 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_delivery_status.py +10 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_endpoint.py +92 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_endpoint_attributes.py +208 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_endpoint_attributes_mode.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_endpoint_envelope.py +92 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_endpoint_envelope_meta.py +61 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_endpoint_list_envelope.py +97 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_endpoint_list_envelope_meta.py +79 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_endpoint_test_result_envelope.py +96 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_endpoint_test_result_envelope_data.py +216 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_endpoint_test_result_envelope_data_error_type_1.py +11 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_endpoint_test_result_envelope_data_error_type_2_type_1.py +11 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_endpoint_test_result_envelope_data_error_type_3_type_1.py +11 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_endpoint_test_result_envelope_data_payload.py +47 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_endpoint_test_result_envelope_meta.py +61 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_subscription.py +153 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_subscription_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_subscription_events_item.py +10 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_subscription_list_envelope.py +99 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_subscription_list_envelope_meta.py +70 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_subscription_with_recent_deliveries_envelope.py +78 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_subscription_with_recent_deliveries_envelope_data.py +179 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_subscription_with_secret_2_envelope.py +76 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_subscription_with_secret_2_envelope_data.py +161 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_subscription_with_secret_envelope.py +76 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_subscription_with_secret_envelope_data.py +163 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_test_result.py +100 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_test_result_envelope.py +74 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/webhook_test_result_payload_preview.py +47 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/wefunder_round.py +367 -0
- wefunder-0.1.0b0/src/wefunder/_generated/models/wefunder_round_status.py +9 -0
- wefunder-0.1.0b0/src/wefunder/_generated/py.typed +0 -0
- wefunder-0.1.0b0/src/wefunder/_generated/types.py +54 -0
- wefunder-0.1.0b0/src/wefunder/_retry.py +208 -0
- wefunder-0.1.0b0/src/wefunder/_version.py +1 -0
- wefunder-0.1.0b0/src/wefunder/client.py +729 -0
- wefunder-0.1.0b0/src/wefunder/errors.py +112 -0
- wefunder-0.1.0b0/src/wefunder/oauth.py +301 -0
- wefunder-0.1.0b0/src/wefunder/pagination.py +73 -0
- wefunder-0.1.0b0/src/wefunder/py.typed +0 -0
- wefunder-0.1.0b0/src/wefunder/token_manager.py +203 -0
- wefunder-0.1.0b0/src/wefunder/webhooks.py +332 -0
wefunder-0.1.0b0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Wefunder, Inc.
|
|
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.
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: wefunder
|
|
3
|
+
Version: 0.1.0b0
|
|
4
|
+
Summary: Official Python SDK for the Wefunder API (beta)
|
|
5
|
+
Project-URL: Homepage, https://github.com/Wefunder/wefunder-python
|
|
6
|
+
Project-URL: Documentation, https://docs.wefunder.com
|
|
7
|
+
Project-URL: Source, https://github.com/Wefunder/wefunder-python
|
|
8
|
+
Project-URL: Issues, https://github.com/Wefunder/wefunder-python/issues
|
|
9
|
+
Author-email: Wefunder <api@wefunder.com>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: api,crowdfunding,oauth,sdk,webhooks,wefunder
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Requires-Dist: attrs>=22.2
|
|
23
|
+
Requires-Dist: httpx<1,>=0.27
|
|
24
|
+
Requires-Dist: python-dateutil>=2.8
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
27
|
+
Requires-Dist: openapi-python-client==0.29.1; extra == 'dev'
|
|
28
|
+
Requires-Dist: pyright>=1.1.400; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
31
|
+
Requires-Dist: pyyaml>=6; extra == 'dev'
|
|
32
|
+
Requires-Dist: ruff==0.16.9; extra == 'dev'
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
# wefunder
|
|
36
|
+
|
|
37
|
+
Official Python SDK for the [Wefunder API](https://docs.wefunder.com). **Beta** — the API is
|
|
38
|
+
pre-launch and `0.x` releases may include breaking changes.
|
|
39
|
+
|
|
40
|
+
- Sync (`Wefunder`) and asyncio (`AsyncWefunder`) clients on [httpx](https://www.python-httpx.org)
|
|
41
|
+
- OAuth 2.0: `client_credentials` for server-to-server, `authorization_code` + PKCE for user consent,
|
|
42
|
+
refresh-token rotation handled for you
|
|
43
|
+
- Automatic retries (rate limits, transient errors) and one-shot token recovery on 401
|
|
44
|
+
- Lazy auto-pagination over opaque cursors
|
|
45
|
+
- Typed errors with the `request_id` support asks for
|
|
46
|
+
- Webhook signature verification, envelope parsing, and dispatch
|
|
47
|
+
- A generated, typed layer for every public operation, plus a `request()` escape hatch
|
|
48
|
+
|
|
49
|
+
Requires Python 3.11+.
|
|
50
|
+
|
|
51
|
+
## Install
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install --pre wefunder
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
`--pre` is needed while the SDK is in beta (PEP 440 pre-releases are not selected by default).
|
|
58
|
+
|
|
59
|
+
## Authentication
|
|
60
|
+
|
|
61
|
+
Wefunder supports two OAuth grants:
|
|
62
|
+
|
|
63
|
+
- Use `client_credentials` for server-to-server access to public data.
|
|
64
|
+
- Use `authorization_code` with PKCE when acting on behalf of a user.
|
|
65
|
+
|
|
66
|
+
### Server-to-server
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
import os
|
|
70
|
+
from wefunder import Wefunder
|
|
71
|
+
|
|
72
|
+
wf = Wefunder.from_client_credentials(
|
|
73
|
+
client_id=os.environ["WEFUNDER_CLIENT_ID"],
|
|
74
|
+
client_secret=os.environ["WEFUNDER_CLIENT_SECRET"],
|
|
75
|
+
scopes=["read:public"],
|
|
76
|
+
)
|
|
77
|
+
page = wf.offerings.list()
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Client-credentials tokens represent the application, not a user. They cannot call user-scoped
|
|
81
|
+
endpoints such as `wf.users.me()` or `wf.portfolio.get()`. The SDK mints a new token automatically
|
|
82
|
+
when a client-credentials token expires.
|
|
83
|
+
|
|
84
|
+
### User authorization with PKCE
|
|
85
|
+
|
|
86
|
+
Generate the authorization URL on your server. Store `state` and the PKCE verifier in the user's
|
|
87
|
+
session before redirecting them:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
import secrets
|
|
91
|
+
from wefunder import create_authorization_url, generate_pkce
|
|
92
|
+
|
|
93
|
+
pkce = generate_pkce()
|
|
94
|
+
state = secrets.token_urlsafe(32)
|
|
95
|
+
save_oauth_attempt(state=state, code_verifier=pkce.code_verifier)
|
|
96
|
+
|
|
97
|
+
url = create_authorization_url(
|
|
98
|
+
client_id=client_id,
|
|
99
|
+
redirect_uri=redirect_uri,
|
|
100
|
+
scopes=["read:investments"],
|
|
101
|
+
state=state,
|
|
102
|
+
pkce=pkce,
|
|
103
|
+
)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The consent host is chosen from the `client_id`: `pk_test_` ids go to the sandbox, everything else to
|
|
107
|
+
wefunder.com. On the callback, validate `state` and exchange the code:
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
from wefunder import Wefunder, exchange_code
|
|
111
|
+
|
|
112
|
+
attempt = consume_oauth_attempt(state)
|
|
113
|
+
tokens = exchange_code(
|
|
114
|
+
client_id=client_id,
|
|
115
|
+
client_secret=client_secret, # omit for public clients
|
|
116
|
+
code=code,
|
|
117
|
+
redirect_uri=redirect_uri,
|
|
118
|
+
code_verifier=attempt.code_verifier,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
wf = Wefunder(tokens=tokens, client_id=client_id, client_secret=client_secret, store=TokenStore())
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Refresh tokens
|
|
125
|
+
|
|
126
|
+
Refresh tokens rotate. When the SDK refreshes an access token it calls `store.save(tokens)` with the
|
|
127
|
+
new set **before** retrying the request. Persist the entire token set each time, and load it yourself
|
|
128
|
+
when constructing a client after a restart:
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
class TokenStore:
|
|
132
|
+
def save(self, tokens): # may be sync or async
|
|
133
|
+
db.save_tokens(tokens.access_token, tokens.refresh_token, tokens.expires_at)
|
|
134
|
+
|
|
135
|
+
wf = Wefunder(tokens=load_tokens(), client_id=client_id, client_secret=client_secret, store=TokenStore())
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Concurrent requests that hit a 401 at the same time share one refresh. If several application
|
|
139
|
+
instances can use the same OAuth connection, serialize refreshes for that connection yourself.
|
|
140
|
+
|
|
141
|
+
## Calling the API
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
offerings = wf.offerings.list(sort="newest")
|
|
145
|
+
investments = wf.investments.list(company_id="co_example")
|
|
146
|
+
portfolio = wf.portfolio.get()
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Namespaces: `users`, `offerings`, `investments`, `portfolio`, `campaigns`, `syndicates`, `intents`,
|
|
150
|
+
`attribution`, and `webhook_endpoints`. Enum-typed query parameters accept plain strings, and
|
|
151
|
+
`datetime` parameters accept ISO-8601 strings.
|
|
152
|
+
|
|
153
|
+
`wf.investments` is the Investment Delta API. `list()` without a cursor bootstraps; pass `updated_since`
|
|
154
|
+
or the `meta.next_cursor` you saved from your last page to receive only records that changed since then.
|
|
155
|
+
`next_cursor` is always present, even on the final page, so persist it after every sync.
|
|
156
|
+
|
|
157
|
+
The API base URL is `https://api.wefunder.com`. Paths are version-free; the SDK sends the API version in
|
|
158
|
+
the `Wefunder-Version` request header.
|
|
159
|
+
|
|
160
|
+
## Pagination
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
# One page, and its cursor.
|
|
164
|
+
page = wf.offerings.list(sort="newest")
|
|
165
|
+
print(page.data, page.meta.next_cursor)
|
|
166
|
+
|
|
167
|
+
# Every item, one page fetched at a time.
|
|
168
|
+
for offering in wf.offerings.all(sort="most_raised"):
|
|
169
|
+
print(offering.id)
|
|
170
|
+
|
|
171
|
+
# Everything in one list.
|
|
172
|
+
investments = wf.investments.collect()
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Cursors are opaque. Pass the value returned by the API without modifying it.
|
|
176
|
+
|
|
177
|
+
## Errors and retries
|
|
178
|
+
|
|
179
|
+
API failures raise `WefunderError`:
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
from wefunder import WefunderError
|
|
183
|
+
|
|
184
|
+
try:
|
|
185
|
+
wf.syndicates.get("syn_example")
|
|
186
|
+
except WefunderError as err:
|
|
187
|
+
print(err.status, err.type, err.message, err.request_id, err.remediation)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The SDK retries idempotent `GET` requests after transient network errors, `5xx` responses, and rate
|
|
191
|
+
limits (honouring `X-RateLimit-Reset`). Write requests are not retried automatically, except once after
|
|
192
|
+
a `401` has been recovered.
|
|
193
|
+
|
|
194
|
+
## Async
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
from wefunder import AsyncWefunder
|
|
198
|
+
|
|
199
|
+
async with await AsyncWefunder.from_client_credentials(client_id=..., client_secret=...) as wf:
|
|
200
|
+
async for offering in wf.offerings.all():
|
|
201
|
+
print(offering.id)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
`AsyncWefunder` has the same plumbing (auth, recovery, retries, typed errors, `raw`, `request()`) and
|
|
205
|
+
namespaces for `users`, `offerings`, `investments`, `portfolio`, and `webhook_endpoints`. Reach every
|
|
206
|
+
other operation with `await wf.call(op, ...)` (see below).
|
|
207
|
+
|
|
208
|
+
## Webhooks
|
|
209
|
+
|
|
210
|
+
Webhooks deliver platform events (`investment.executed`, `offering.opened`, `investment.changed`, …) to
|
|
211
|
+
an HTTPS endpoint you register. Every delivery is signed; the SDK verifies the signature, parses the
|
|
212
|
+
envelope, and hands you an event.
|
|
213
|
+
|
|
214
|
+
### 1. Register an endpoint
|
|
215
|
+
|
|
216
|
+
Endpoints belong to your application and are managed through the live API (scope `write:webhooks`).
|
|
217
|
+
The signing secret is returned only on create and rotate, so store it immediately.
|
|
218
|
+
|
|
219
|
+
```python
|
|
220
|
+
endpoint = wf.webhook_endpoints.create(
|
|
221
|
+
url="https://yourapp.com/webhooks/wefunder", # public HTTPS; localhost and private IPs are rejected
|
|
222
|
+
events=["offering.opened", "investment.executed"],
|
|
223
|
+
mode="live", # "test" endpoints receive sandbox events
|
|
224
|
+
)
|
|
225
|
+
save_secret(endpoint.attributes.secret)
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
`wf.webhook_endpoints` also provides `list`, `get`, `update`, `remove`, `rotate_secret`, `reenable`,
|
|
229
|
+
and `test`.
|
|
230
|
+
|
|
231
|
+
### 2. Verify and handle deliveries
|
|
232
|
+
|
|
233
|
+
Pass the **raw** request body, the headers, and your secret to `construct_event`. It raises
|
|
234
|
+
`WebhookSignatureError` (with a `reason`) when a delivery is not authentic.
|
|
235
|
+
|
|
236
|
+
```python
|
|
237
|
+
from wefunder import WebhookSignatureError, construct_event, dispatch_webhook
|
|
238
|
+
|
|
239
|
+
@app.post("/webhooks/wefunder")
|
|
240
|
+
def receive(request):
|
|
241
|
+
try:
|
|
242
|
+
event = construct_event(request.get_data(), request.headers, WEBHOOK_SECRET)
|
|
243
|
+
except WebhookSignatureError as err:
|
|
244
|
+
return err.reason, 400
|
|
245
|
+
|
|
246
|
+
dispatch_webhook(event, {
|
|
247
|
+
"investment.executed": lambda e: record_funding(e.data["id"], e.data["amounts"]["committed"]),
|
|
248
|
+
"offering.opened": lambda e: announce(e.data["company"]["name"]),
|
|
249
|
+
"default": lambda e: log.info("unhandled %s", e.event),
|
|
250
|
+
})
|
|
251
|
+
return "", 200
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Deliveries are at-least-once and unordered. Deduplicate on `event.id`, and where a payload carries
|
|
255
|
+
`occurred_at`, keep the state from the latest one you have seen. `async_dispatch_webhook` accepts
|
|
256
|
+
coroutine handlers.
|
|
257
|
+
|
|
258
|
+
### 3. Test your handler
|
|
259
|
+
|
|
260
|
+
`wf.webhook_endpoints.test(endpoint.id)` sends a real, signed example event and reports the outcome.
|
|
261
|
+
To unit-test your handler without the API, sign a fixture yourself:
|
|
262
|
+
|
|
263
|
+
```python
|
|
264
|
+
from wefunder import sign_webhook
|
|
265
|
+
|
|
266
|
+
header = sign_webhook(body, secret)
|
|
267
|
+
# POST `body` to your handler with `Wefunder-Signature: <header>`
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Signature scheme
|
|
271
|
+
|
|
272
|
+
Each delivery carries `Wefunder-Signature: t=<unix seconds>,v1=<hex>` where `v1` is
|
|
273
|
+
`HMAC-SHA256(secret, "<t>.<raw body>")`. Requests whose `t` is more than five minutes from now are
|
|
274
|
+
rejected (`tolerance_seconds` adjusts this). During a secret rotation the header carries one `v1` per
|
|
275
|
+
active secret and `construct_event` accepts either. `verify_webhook` and `check_webhook_signature`
|
|
276
|
+
expose the check without parsing, and `construct_event` still accepts the retired attribution headers
|
|
277
|
+
(`X-Wefunder-Signature` / `X-Wefunder-Timestamp`).
|
|
278
|
+
|
|
279
|
+
## Generated operations
|
|
280
|
+
|
|
281
|
+
Typed namespaces cover the common resources. Every operation in the public OpenAPI specification is
|
|
282
|
+
generated under `wefunder._generated.api.<tag>`; call one through the client to get the same auth,
|
|
283
|
+
retries, and error handling:
|
|
284
|
+
|
|
285
|
+
```python
|
|
286
|
+
from wefunder._generated.api.syndicate_members import list_syndicate_members
|
|
287
|
+
|
|
288
|
+
members = wf.call(list_syndicate_members, syndicate_id="syn_example")
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
For a path the generated layer does not know yet, `wf.request(method, path, query=..., body=...,
|
|
292
|
+
headers=...)` sends a fully-wrapped request and returns the decoded JSON.
|
|
293
|
+
|
|
294
|
+
## Development
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
python -m venv .venv && . .venv/bin/activate
|
|
298
|
+
pip install -e ".[dev]"
|
|
299
|
+
ruff check src tests scripts examples && ruff format --check src tests scripts examples
|
|
300
|
+
pyright
|
|
301
|
+
pytest
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
`pytest tests/e2e -o addopts=""` runs against the sandbox when `WEFUNDER_CLIENT_ID` and
|
|
305
|
+
`WEFUNDER_CLIENT_SECRET` are set.
|
|
306
|
+
|
|
307
|
+
Generated files in `src/wefunder/_generated/` come from `spec/openapi.yaml` and are never edited by
|
|
308
|
+
hand.
|
|
309
|
+
|
|
310
|
+
### Conformance vectors
|
|
311
|
+
|
|
312
|
+
`conformance/*.json` is the cross-language behavioural contract shared with `wefunder-node` (and the
|
|
313
|
+
Ruby SDK): signatures, token rotation, pagination, retries, errors. `tests/test_conformance.py` runs
|
|
314
|
+
every case against both clients. The files are vendored from `Wefunder/wefunder-node` at the ref in
|
|
315
|
+
`conformance/PIN`; refresh with `python scripts/sync_conformance.py [ref]`. Never edit a vector to make
|
|
316
|
+
the shell pass.
|
|
317
|
+
|
|
318
|
+
### Examples
|
|
319
|
+
|
|
320
|
+
`examples/` is the source of truth for the Python snippets on docs.wefunder.com; see
|
|
321
|
+
`examples/README.md`. After adding one, run `python scripts/build_examples_manifest.py` and remove its
|
|
322
|
+
`operationId` from `examples/coverage-allowlist.json`.
|
|
323
|
+
|
|
324
|
+
### Updating the API specification
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
python scripts/sync_spec.py /path/to/wefunder # public-tier spec → spec/openapi.yaml
|
|
328
|
+
python scripts/generate.py # → src/wefunder/_generated
|
|
329
|
+
pyright && pytest
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Commit the specification and generated client together.
|
|
333
|
+
|
|
334
|
+
### Releasing
|
|
335
|
+
|
|
336
|
+
Set the version in `src/wefunder/_version.py` (PEP 440, e.g. `0.1.0b1`), rebuild
|
|
337
|
+
`examples_manifest.json`, commit, then:
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
git tag v0.1.0b1
|
|
341
|
+
git push --follow-tags
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
The release workflow verifies the tag, runs the checks, builds, and publishes to PyPI via trusted
|
|
345
|
+
publishing.
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
# wefunder
|
|
2
|
+
|
|
3
|
+
Official Python SDK for the [Wefunder API](https://docs.wefunder.com). **Beta** — the API is
|
|
4
|
+
pre-launch and `0.x` releases may include breaking changes.
|
|
5
|
+
|
|
6
|
+
- Sync (`Wefunder`) and asyncio (`AsyncWefunder`) clients on [httpx](https://www.python-httpx.org)
|
|
7
|
+
- OAuth 2.0: `client_credentials` for server-to-server, `authorization_code` + PKCE for user consent,
|
|
8
|
+
refresh-token rotation handled for you
|
|
9
|
+
- Automatic retries (rate limits, transient errors) and one-shot token recovery on 401
|
|
10
|
+
- Lazy auto-pagination over opaque cursors
|
|
11
|
+
- Typed errors with the `request_id` support asks for
|
|
12
|
+
- Webhook signature verification, envelope parsing, and dispatch
|
|
13
|
+
- A generated, typed layer for every public operation, plus a `request()` escape hatch
|
|
14
|
+
|
|
15
|
+
Requires Python 3.11+.
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install --pre wefunder
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`--pre` is needed while the SDK is in beta (PEP 440 pre-releases are not selected by default).
|
|
24
|
+
|
|
25
|
+
## Authentication
|
|
26
|
+
|
|
27
|
+
Wefunder supports two OAuth grants:
|
|
28
|
+
|
|
29
|
+
- Use `client_credentials` for server-to-server access to public data.
|
|
30
|
+
- Use `authorization_code` with PKCE when acting on behalf of a user.
|
|
31
|
+
|
|
32
|
+
### Server-to-server
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
import os
|
|
36
|
+
from wefunder import Wefunder
|
|
37
|
+
|
|
38
|
+
wf = Wefunder.from_client_credentials(
|
|
39
|
+
client_id=os.environ["WEFUNDER_CLIENT_ID"],
|
|
40
|
+
client_secret=os.environ["WEFUNDER_CLIENT_SECRET"],
|
|
41
|
+
scopes=["read:public"],
|
|
42
|
+
)
|
|
43
|
+
page = wf.offerings.list()
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Client-credentials tokens represent the application, not a user. They cannot call user-scoped
|
|
47
|
+
endpoints such as `wf.users.me()` or `wf.portfolio.get()`. The SDK mints a new token automatically
|
|
48
|
+
when a client-credentials token expires.
|
|
49
|
+
|
|
50
|
+
### User authorization with PKCE
|
|
51
|
+
|
|
52
|
+
Generate the authorization URL on your server. Store `state` and the PKCE verifier in the user's
|
|
53
|
+
session before redirecting them:
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
import secrets
|
|
57
|
+
from wefunder import create_authorization_url, generate_pkce
|
|
58
|
+
|
|
59
|
+
pkce = generate_pkce()
|
|
60
|
+
state = secrets.token_urlsafe(32)
|
|
61
|
+
save_oauth_attempt(state=state, code_verifier=pkce.code_verifier)
|
|
62
|
+
|
|
63
|
+
url = create_authorization_url(
|
|
64
|
+
client_id=client_id,
|
|
65
|
+
redirect_uri=redirect_uri,
|
|
66
|
+
scopes=["read:investments"],
|
|
67
|
+
state=state,
|
|
68
|
+
pkce=pkce,
|
|
69
|
+
)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The consent host is chosen from the `client_id`: `pk_test_` ids go to the sandbox, everything else to
|
|
73
|
+
wefunder.com. On the callback, validate `state` and exchange the code:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from wefunder import Wefunder, exchange_code
|
|
77
|
+
|
|
78
|
+
attempt = consume_oauth_attempt(state)
|
|
79
|
+
tokens = exchange_code(
|
|
80
|
+
client_id=client_id,
|
|
81
|
+
client_secret=client_secret, # omit for public clients
|
|
82
|
+
code=code,
|
|
83
|
+
redirect_uri=redirect_uri,
|
|
84
|
+
code_verifier=attempt.code_verifier,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
wf = Wefunder(tokens=tokens, client_id=client_id, client_secret=client_secret, store=TokenStore())
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Refresh tokens
|
|
91
|
+
|
|
92
|
+
Refresh tokens rotate. When the SDK refreshes an access token it calls `store.save(tokens)` with the
|
|
93
|
+
new set **before** retrying the request. Persist the entire token set each time, and load it yourself
|
|
94
|
+
when constructing a client after a restart:
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
class TokenStore:
|
|
98
|
+
def save(self, tokens): # may be sync or async
|
|
99
|
+
db.save_tokens(tokens.access_token, tokens.refresh_token, tokens.expires_at)
|
|
100
|
+
|
|
101
|
+
wf = Wefunder(tokens=load_tokens(), client_id=client_id, client_secret=client_secret, store=TokenStore())
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Concurrent requests that hit a 401 at the same time share one refresh. If several application
|
|
105
|
+
instances can use the same OAuth connection, serialize refreshes for that connection yourself.
|
|
106
|
+
|
|
107
|
+
## Calling the API
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
offerings = wf.offerings.list(sort="newest")
|
|
111
|
+
investments = wf.investments.list(company_id="co_example")
|
|
112
|
+
portfolio = wf.portfolio.get()
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Namespaces: `users`, `offerings`, `investments`, `portfolio`, `campaigns`, `syndicates`, `intents`,
|
|
116
|
+
`attribution`, and `webhook_endpoints`. Enum-typed query parameters accept plain strings, and
|
|
117
|
+
`datetime` parameters accept ISO-8601 strings.
|
|
118
|
+
|
|
119
|
+
`wf.investments` is the Investment Delta API. `list()` without a cursor bootstraps; pass `updated_since`
|
|
120
|
+
or the `meta.next_cursor` you saved from your last page to receive only records that changed since then.
|
|
121
|
+
`next_cursor` is always present, even on the final page, so persist it after every sync.
|
|
122
|
+
|
|
123
|
+
The API base URL is `https://api.wefunder.com`. Paths are version-free; the SDK sends the API version in
|
|
124
|
+
the `Wefunder-Version` request header.
|
|
125
|
+
|
|
126
|
+
## Pagination
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
# One page, and its cursor.
|
|
130
|
+
page = wf.offerings.list(sort="newest")
|
|
131
|
+
print(page.data, page.meta.next_cursor)
|
|
132
|
+
|
|
133
|
+
# Every item, one page fetched at a time.
|
|
134
|
+
for offering in wf.offerings.all(sort="most_raised"):
|
|
135
|
+
print(offering.id)
|
|
136
|
+
|
|
137
|
+
# Everything in one list.
|
|
138
|
+
investments = wf.investments.collect()
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Cursors are opaque. Pass the value returned by the API without modifying it.
|
|
142
|
+
|
|
143
|
+
## Errors and retries
|
|
144
|
+
|
|
145
|
+
API failures raise `WefunderError`:
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
from wefunder import WefunderError
|
|
149
|
+
|
|
150
|
+
try:
|
|
151
|
+
wf.syndicates.get("syn_example")
|
|
152
|
+
except WefunderError as err:
|
|
153
|
+
print(err.status, err.type, err.message, err.request_id, err.remediation)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The SDK retries idempotent `GET` requests after transient network errors, `5xx` responses, and rate
|
|
157
|
+
limits (honouring `X-RateLimit-Reset`). Write requests are not retried automatically, except once after
|
|
158
|
+
a `401` has been recovered.
|
|
159
|
+
|
|
160
|
+
## Async
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
from wefunder import AsyncWefunder
|
|
164
|
+
|
|
165
|
+
async with await AsyncWefunder.from_client_credentials(client_id=..., client_secret=...) as wf:
|
|
166
|
+
async for offering in wf.offerings.all():
|
|
167
|
+
print(offering.id)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
`AsyncWefunder` has the same plumbing (auth, recovery, retries, typed errors, `raw`, `request()`) and
|
|
171
|
+
namespaces for `users`, `offerings`, `investments`, `portfolio`, and `webhook_endpoints`. Reach every
|
|
172
|
+
other operation with `await wf.call(op, ...)` (see below).
|
|
173
|
+
|
|
174
|
+
## Webhooks
|
|
175
|
+
|
|
176
|
+
Webhooks deliver platform events (`investment.executed`, `offering.opened`, `investment.changed`, …) to
|
|
177
|
+
an HTTPS endpoint you register. Every delivery is signed; the SDK verifies the signature, parses the
|
|
178
|
+
envelope, and hands you an event.
|
|
179
|
+
|
|
180
|
+
### 1. Register an endpoint
|
|
181
|
+
|
|
182
|
+
Endpoints belong to your application and are managed through the live API (scope `write:webhooks`).
|
|
183
|
+
The signing secret is returned only on create and rotate, so store it immediately.
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
endpoint = wf.webhook_endpoints.create(
|
|
187
|
+
url="https://yourapp.com/webhooks/wefunder", # public HTTPS; localhost and private IPs are rejected
|
|
188
|
+
events=["offering.opened", "investment.executed"],
|
|
189
|
+
mode="live", # "test" endpoints receive sandbox events
|
|
190
|
+
)
|
|
191
|
+
save_secret(endpoint.attributes.secret)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
`wf.webhook_endpoints` also provides `list`, `get`, `update`, `remove`, `rotate_secret`, `reenable`,
|
|
195
|
+
and `test`.
|
|
196
|
+
|
|
197
|
+
### 2. Verify and handle deliveries
|
|
198
|
+
|
|
199
|
+
Pass the **raw** request body, the headers, and your secret to `construct_event`. It raises
|
|
200
|
+
`WebhookSignatureError` (with a `reason`) when a delivery is not authentic.
|
|
201
|
+
|
|
202
|
+
```python
|
|
203
|
+
from wefunder import WebhookSignatureError, construct_event, dispatch_webhook
|
|
204
|
+
|
|
205
|
+
@app.post("/webhooks/wefunder")
|
|
206
|
+
def receive(request):
|
|
207
|
+
try:
|
|
208
|
+
event = construct_event(request.get_data(), request.headers, WEBHOOK_SECRET)
|
|
209
|
+
except WebhookSignatureError as err:
|
|
210
|
+
return err.reason, 400
|
|
211
|
+
|
|
212
|
+
dispatch_webhook(event, {
|
|
213
|
+
"investment.executed": lambda e: record_funding(e.data["id"], e.data["amounts"]["committed"]),
|
|
214
|
+
"offering.opened": lambda e: announce(e.data["company"]["name"]),
|
|
215
|
+
"default": lambda e: log.info("unhandled %s", e.event),
|
|
216
|
+
})
|
|
217
|
+
return "", 200
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Deliveries are at-least-once and unordered. Deduplicate on `event.id`, and where a payload carries
|
|
221
|
+
`occurred_at`, keep the state from the latest one you have seen. `async_dispatch_webhook` accepts
|
|
222
|
+
coroutine handlers.
|
|
223
|
+
|
|
224
|
+
### 3. Test your handler
|
|
225
|
+
|
|
226
|
+
`wf.webhook_endpoints.test(endpoint.id)` sends a real, signed example event and reports the outcome.
|
|
227
|
+
To unit-test your handler without the API, sign a fixture yourself:
|
|
228
|
+
|
|
229
|
+
```python
|
|
230
|
+
from wefunder import sign_webhook
|
|
231
|
+
|
|
232
|
+
header = sign_webhook(body, secret)
|
|
233
|
+
# POST `body` to your handler with `Wefunder-Signature: <header>`
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Signature scheme
|
|
237
|
+
|
|
238
|
+
Each delivery carries `Wefunder-Signature: t=<unix seconds>,v1=<hex>` where `v1` is
|
|
239
|
+
`HMAC-SHA256(secret, "<t>.<raw body>")`. Requests whose `t` is more than five minutes from now are
|
|
240
|
+
rejected (`tolerance_seconds` adjusts this). During a secret rotation the header carries one `v1` per
|
|
241
|
+
active secret and `construct_event` accepts either. `verify_webhook` and `check_webhook_signature`
|
|
242
|
+
expose the check without parsing, and `construct_event` still accepts the retired attribution headers
|
|
243
|
+
(`X-Wefunder-Signature` / `X-Wefunder-Timestamp`).
|
|
244
|
+
|
|
245
|
+
## Generated operations
|
|
246
|
+
|
|
247
|
+
Typed namespaces cover the common resources. Every operation in the public OpenAPI specification is
|
|
248
|
+
generated under `wefunder._generated.api.<tag>`; call one through the client to get the same auth,
|
|
249
|
+
retries, and error handling:
|
|
250
|
+
|
|
251
|
+
```python
|
|
252
|
+
from wefunder._generated.api.syndicate_members import list_syndicate_members
|
|
253
|
+
|
|
254
|
+
members = wf.call(list_syndicate_members, syndicate_id="syn_example")
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
For a path the generated layer does not know yet, `wf.request(method, path, query=..., body=...,
|
|
258
|
+
headers=...)` sends a fully-wrapped request and returns the decoded JSON.
|
|
259
|
+
|
|
260
|
+
## Development
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
python -m venv .venv && . .venv/bin/activate
|
|
264
|
+
pip install -e ".[dev]"
|
|
265
|
+
ruff check src tests scripts examples && ruff format --check src tests scripts examples
|
|
266
|
+
pyright
|
|
267
|
+
pytest
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
`pytest tests/e2e -o addopts=""` runs against the sandbox when `WEFUNDER_CLIENT_ID` and
|
|
271
|
+
`WEFUNDER_CLIENT_SECRET` are set.
|
|
272
|
+
|
|
273
|
+
Generated files in `src/wefunder/_generated/` come from `spec/openapi.yaml` and are never edited by
|
|
274
|
+
hand.
|
|
275
|
+
|
|
276
|
+
### Conformance vectors
|
|
277
|
+
|
|
278
|
+
`conformance/*.json` is the cross-language behavioural contract shared with `wefunder-node` (and the
|
|
279
|
+
Ruby SDK): signatures, token rotation, pagination, retries, errors. `tests/test_conformance.py` runs
|
|
280
|
+
every case against both clients. The files are vendored from `Wefunder/wefunder-node` at the ref in
|
|
281
|
+
`conformance/PIN`; refresh with `python scripts/sync_conformance.py [ref]`. Never edit a vector to make
|
|
282
|
+
the shell pass.
|
|
283
|
+
|
|
284
|
+
### Examples
|
|
285
|
+
|
|
286
|
+
`examples/` is the source of truth for the Python snippets on docs.wefunder.com; see
|
|
287
|
+
`examples/README.md`. After adding one, run `python scripts/build_examples_manifest.py` and remove its
|
|
288
|
+
`operationId` from `examples/coverage-allowlist.json`.
|
|
289
|
+
|
|
290
|
+
### Updating the API specification
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
python scripts/sync_spec.py /path/to/wefunder # public-tier spec → spec/openapi.yaml
|
|
294
|
+
python scripts/generate.py # → src/wefunder/_generated
|
|
295
|
+
pyright && pytest
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Commit the specification and generated client together.
|
|
299
|
+
|
|
300
|
+
### Releasing
|
|
301
|
+
|
|
302
|
+
Set the version in `src/wefunder/_version.py` (PEP 440, e.g. `0.1.0b1`), rebuild
|
|
303
|
+
`examples_manifest.json`, commit, then:
|
|
304
|
+
|
|
305
|
+
```bash
|
|
306
|
+
git tag v0.1.0b1
|
|
307
|
+
git push --follow-tags
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
The release workflow verifies the tag, runs the checks, builds, and publishes to PyPI via trusted
|
|
311
|
+
publishing.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# examples/ — the source of truth for docs code samples
|
|
2
|
+
|
|
3
|
+
Mirrors `wefunder-node/examples/README.md` (the cross-language contract). Each file is a real,
|
|
4
|
+
type-checked module exporting `example(wf)`. A `# region <key>` … `# endregion` block marks the
|
|
5
|
+
snippet shown on docs.wefunder.com; everything outside it is harness. `<key>` is an
|
|
6
|
+
`operationId` (auto-binds to that operation's Python tab) or `guides/<name>`.
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
python scripts/build_examples_manifest.py # → examples_manifest.json (lang "Python")
|
|
10
|
+
pyright examples # compile gate
|
|
11
|
+
pytest tests/test_examples.py # coverage + freshness + shape gates
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Every public `operationId` in `spec/openapi.yaml` must have an example here or be listed in
|
|
15
|
+
`coverage-allowlist.json` (curl-only). Files starting with `_` are hidden harness.
|