|
| 1 | + |
| 2 | + |
| 3 | +<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! --> |
| 4 | + |
| 5 | +``` python |
| 6 | +stripe_openapi_url = 'https://raw.githubusercontent.com/stripe/openapi/refs/heads/master/openapi/spec3.json' |
| 7 | +stripe_spec = urlsend(stripe_openapi_url, 'GET', return_json=True) |
| 8 | +stripe_spec.keys() |
| 9 | +``` |
| 10 | + |
| 11 | + dict_keys(['components', 'info', 'openapi', 'paths', 'security', 'servers']) |
| 12 | + |
| 13 | +https://docs.stripe.com/api/capabilities/update |
| 14 | +https://docs.stripe.com/api/persons/create?api-version=2025-03-31.basil |
| 15 | + |
| 16 | +The OpenAPI spec describes how a particular REST API works. The most |
| 17 | +important part of this spec is the paths that are defined by a |
| 18 | +particular spec. This defines what you can do with a particular API and |
| 19 | +usually includes things like the description of endpoint, expected |
| 20 | +parameters, the description of the parameters, and a schema of what will |
| 21 | +be returned from a particular endpoint. |
| 22 | + |
| 23 | +``` python |
| 24 | +path, verbs = first(stripe_spec['paths'].items()) |
| 25 | +path, verbs.keys() |
| 26 | +``` |
| 27 | + |
| 28 | + ('/v1/account', dict_keys(['get'])) |
| 29 | + |
| 30 | +``` python |
| 31 | +verbs['get'].keys() |
| 32 | +``` |
| 33 | + |
| 34 | + dict_keys(['description', 'operationId', 'parameters', 'requestBody', 'responses', 'summary']) |
| 35 | + |
| 36 | +As we can see here, the account path has a single HTTP verb that we can |
| 37 | +use on it called GET. The verb + path is what we refer to as an |
| 38 | +endpoint. This endpoint allows us to get the account details for a |
| 39 | +stripe. |
| 40 | + |
| 41 | +``` python |
| 42 | +stripe_api_url = 'https://api.stripe.com' |
| 43 | +ep = stripe_api_url + path |
| 44 | +ep |
| 45 | +``` |
| 46 | + |
| 47 | + 'https://api.stripe.com/v1/account' |
| 48 | + |
| 49 | +``` python |
| 50 | +stripe_key = os.environ['STRIPE_SECRET_KEY'] |
| 51 | +headers = {'Authorization': f'Bearer {stripe_key}'} |
| 52 | +resp = urlsend(ep, 'GET', headers=headers) |
| 53 | +resp.keys() |
| 54 | +``` |
| 55 | + |
| 56 | + dict_keys(['id', 'object', 'business_type', 'capabilities', 'charges_enabled', 'country', 'default_currency', 'details_submitted', 'payouts_enabled', 'settings', 'type']) |
| 57 | + |
| 58 | +Some of these endpoints will take parameters if they are GET verbs or |
| 59 | +request bodies. POST verbs. Here is an example for the GET customers |
| 60 | +endpoint |
| 61 | + |
| 62 | +``` python |
| 63 | +path, verbs = first(stripe_spec['paths'].items(), lambda x: x[0] == '/v1/customers') |
| 64 | +verbs['get']['parameters'][0] |
| 65 | +``` |
| 66 | + |
| 67 | + {'description': 'Only return customers that were created during the given date interval.', |
| 68 | + 'explode': True, |
| 69 | + 'in': 'query', |
| 70 | + 'name': 'created', |
| 71 | + 'required': False, |
| 72 | + 'schema': {'anyOf': [{'properties': {'gt': {'type': 'integer'}, |
| 73 | + 'gte': {'type': 'integer'}, |
| 74 | + 'lt': {'type': 'integer'}, |
| 75 | + 'lte': {'type': 'integer'}}, |
| 76 | + 'title': 'range_query_specs', |
| 77 | + 'type': 'object'}, |
| 78 | + {'type': 'integer'}]}, |
| 79 | + 'style': 'deepObject'} |
| 80 | + |
| 81 | +And here is one for a post |
| 82 | + |
| 83 | +``` python |
| 84 | +first(nested_idx(verbs, *'post requestBody content application/x-www-form-urlencoded schema properties'.split()).items()) |
| 85 | +``` |
| 86 | + |
| 87 | + ('address', |
| 88 | + {'anyOf': [{'properties': {'city': {'maxLength': 5000, 'type': 'string'}, |
| 89 | + 'country': {'maxLength': 5000, 'type': 'string'}, |
| 90 | + 'line1': {'maxLength': 5000, 'type': 'string'}, |
| 91 | + 'line2': {'maxLength': 5000, 'type': 'string'}, |
| 92 | + 'postal_code': {'maxLength': 5000, 'type': 'string'}, |
| 93 | + 'state': {'maxLength': 5000, 'type': 'string'}}, |
| 94 | + 'title': 'optional_fields_customer_address', |
| 95 | + 'type': 'object'}, |
| 96 | + {'enum': [''], 'type': 'string'}], |
| 97 | + 'description': "The customer's address."}) |
| 98 | + |
| 99 | +Depending on the spec, the encoding might be json or form url encoded. |
| 100 | +For Stripe, form url encoded is used. |
| 101 | + |
| 102 | +Finally, parameters can be inside the path itself |
| 103 | + |
| 104 | +``` python |
| 105 | +path, verbs = first(stripe_spec['paths'].items(), lambda x: '{' in x[0]) |
| 106 | +path, verbs.keys() |
| 107 | +``` |
| 108 | + |
| 109 | + ('/v1/accounts/{account}', dict_keys(['delete', 'get', 'post'])) |
| 110 | + |
| 111 | +`fastcore` luckily has some pretty nifty helper functions to deal with |
| 112 | +path parameters |
| 113 | + |
| 114 | +``` python |
| 115 | +path, *_ = partial_format(path) |
| 116 | +route_ps = stringfmt_names(path) |
| 117 | +route_ps |
| 118 | +``` |
| 119 | + |
| 120 | + ['account'] |
| 121 | + |
| 122 | +For post parameters, we can get data type information that we can |
| 123 | +surface to developers. |
| 124 | + |
| 125 | +``` python |
| 126 | +_lu_type |
| 127 | +``` |
| 128 | + |
| 129 | + {'NA': object, |
| 130 | + 'string': str, |
| 131 | + 'object': dict, |
| 132 | + 'array': list, |
| 133 | + 'boolean': bool, |
| 134 | + 'number': int, |
| 135 | + 'integer': int} |
| 136 | + |
| 137 | +``` python |
| 138 | +d = first(_find_data(verbs['post'], 'application/x-www-form-urlencoded').items()) |
| 139 | +d |
| 140 | +``` |
| 141 | + |
| 142 | + ('account_token', |
| 143 | + {'description': 'An [account token](https://stripe.com/docs/api#create_account_token), used to securely provide details to the account.', |
| 144 | + 'maxLength': 5000, |
| 145 | + 'type': 'string'}) |
| 146 | + |
| 147 | +``` python |
| 148 | +deets = _deets(*d) |
| 149 | +deets |
| 150 | +``` |
| 151 | + |
| 152 | + {'name': 'account_token', |
| 153 | + 'description': 'An [account token](https://stripe.com/docs/api#create_account_token), used to securely provide details to the account.', |
| 154 | + 'annotation': str, |
| 155 | + 'default': None} |
| 156 | + |
| 157 | +While get requests can technically also have bodies, these are normally |
| 158 | +ignored by HTTP servers. |
| 159 | + |
| 160 | +The data we care most about for interfacing with an OpenAPI spec are the |
| 161 | +data, operation id, query parameters, summary, and url. So, lets make a |
| 162 | +helper function to grab these tidbits |
| 163 | + |
| 164 | +``` python |
| 165 | +info = _info(verbs['get']) |
| 166 | +first(info['data']), info['op_id'], first(info['qparams']), info['summary'] |
| 167 | +``` |
| 168 | + |
| 169 | + (None, |
| 170 | + 'GetAccountsAccount', |
| 171 | + {'name': 'expand', |
| 172 | + 'description': 'Specifies which fields in the response should be expanded.', |
| 173 | + 'annotation': 'str'}, |
| 174 | + 'Retrieve account') |
| 175 | + |
| 176 | +``` python |
| 177 | +info = _info(verbs['post']) |
| 178 | +first(info['data']), info['op_id'], first(info['qparams']), info['summary'] |
| 179 | +``` |
| 180 | + |
| 181 | + ({'name': 'account_token', |
| 182 | + 'description': 'An [account token](https://stripe.com/docs/api#create_account_token), used to securely provide details to the account.', |
| 183 | + 'annotation': str, |
| 184 | + 'default': None}, |
| 185 | + 'PostAccountsAccount', |
| 186 | + None, |
| 187 | + 'Update an account') |
| 188 | + |
| 189 | +``` python |
| 190 | +_durl(path, 'get') |
| 191 | +``` |
| 192 | + |
| 193 | + 'https://docs.stripe.com/api/accounts/delete' |
| 194 | + |
| 195 | +------------------------------------------------------------------------ |
| 196 | + |
| 197 | +<a |
| 198 | +href="https://github.com/AnswerDotAI/faststripe/blob/main/faststripe/spec.py#L72" |
| 199 | +target="_blank" style="float:right; font-size:smaller">source</a> |
| 200 | + |
| 201 | +### build_eps |
| 202 | + |
| 203 | +> build_eps (url) |
| 204 | +
|
| 205 | +*Build module metadata.py from an Open API spec and optionally filter by |
| 206 | +a path `pre`* |
| 207 | + |
| 208 | +``` python |
| 209 | +eps = build_eps(stripe_openapi_url) |
| 210 | +eps[0] |
| 211 | +``` |
| 212 | + |
| 213 | + {'path': '/v1/account', |
| 214 | + 'verb': 'get', |
| 215 | + 'data': [], |
| 216 | + 'op_id': 'GetAccount', |
| 217 | + 'qparams': [{'name': 'expand', |
| 218 | + 'description': 'Specifies which fields in the response should be expanded.', |
| 219 | + 'annotation': 'str'}], |
| 220 | + 'summary': 'Retrieve account', |
| 221 | + 'doc_url': 'https://docs.stripe.com/api/accounts/retrieve'} |
| 222 | + |
| 223 | +------------------------------------------------------------------------ |
| 224 | + |
| 225 | +<a |
| 226 | +href="https://github.com/AnswerDotAI/faststripe/blob/main/faststripe/spec.py#L81" |
| 227 | +target="_blank" style="float:right; font-size:smaller">source</a> |
| 228 | + |
| 229 | +### update_version |
| 230 | + |
| 231 | +> update_version () |
| 232 | +
|
| 233 | +*Update the version to the latest version of the Stripe API and the |
| 234 | +endpoints file.* |
| 235 | + |
| 236 | +``` python |
| 237 | +update_version() |
| 238 | +``` |
| 239 | + |
| 240 | + Updated version to 2025.07.30 |
0 commit comments