From e0635389cd85dfbc58258c8711d5a0b0b9691a9c Mon Sep 17 00:00:00 2001 From: Bartosz Date: Fri, 12 Jun 2026 01:14:36 +0200 Subject: [PATCH] Add Fern SDK generator scaffold Add a fern/ directory with generators.yml declaring the fern-python-sdk generator group and an OpenAPI spec covering the scoring, Lists, Privacy and Events endpoints. Generated output is written to ../generated/python and is not committed. --- fern/README.md | 21 ++++ fern/fern.config.json | 4 + fern/generators.yml | 13 +++ fern/openapi/openapi.yml | 240 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 278 insertions(+) create mode 100644 fern/README.md create mode 100644 fern/fern.config.json create mode 100644 fern/generators.yml create mode 100644 fern/openapi/openapi.yml diff --git a/fern/README.md b/fern/README.md new file mode 100644 index 0000000..6d4ead9 --- /dev/null +++ b/fern/README.md @@ -0,0 +1,21 @@ +# Fern scaffold (proposal) + +This directory is a proposal for generating the Castle Python SDK surface with +[Fern](https://buildwithfern.com) from an OpenAPI specification. + +## Layout + +- `fern.config.json` — organization name and pinned Fern CLI version. +- `generators.yml` — declares the API spec and the `fern-python-sdk` generator group. +- `openapi/openapi.yml` — OpenAPI spec for the Castle scoring, Lists, Privacy + and Events endpoints used as the generator input. + +## Usage + +```bash +npm install -g fern-api +fern check +fern generate --group python-sdk --local +``` + +Generated code is written to `../generated/python` and is not committed. diff --git a/fern/fern.config.json b/fern/fern.config.json new file mode 100644 index 0000000..460b099 --- /dev/null +++ b/fern/fern.config.json @@ -0,0 +1,4 @@ +{ + "organization": "castle", + "version": "5.47.1" +} diff --git a/fern/generators.yml b/fern/generators.yml new file mode 100644 index 0000000..adc2ed9 --- /dev/null +++ b/fern/generators.yml @@ -0,0 +1,13 @@ +api: + specs: + - openapi: ./openapi/openapi.yml +groups: + python-sdk: + generators: + - name: fernapi/fern-python-sdk + version: 5.14.14 + output: + location: local-file-system + path: ../generated/python + github: + repository: castle/castle-python diff --git a/fern/openapi/openapi.yml b/fern/openapi/openapi.yml new file mode 100644 index 0000000..05fd9f0 --- /dev/null +++ b/fern/openapi/openapi.yml @@ -0,0 +1,240 @@ +openapi: 3.0.3 +info: + title: Castle API + version: "1.0.0" + description: > + Server-side Castle API covering the scoring endpoints (risk, filter, log), + the Lists and Privacy management endpoints, and the Events API. This + specification is the input for Fern SDK generation. + license: + name: MIT + url: https://opensource.org/licenses/MIT +servers: + - url: https://api.castle.io/v1 +security: + - apiSecret: [] +tags: + - name: Scoring + - name: Lists + - name: Privacy + - name: Events +paths: + /risk: + post: + operationId: risk + tags: [Scoring] + summary: Evaluate the risk of an authenticated event. + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/ScoringRequest" + responses: + "200": + description: Verdict for the evaluated event. + content: + application/json: + schema: + $ref: "#/components/schemas/Verdict" + /filter: + post: + operationId: filter + tags: [Scoring] + summary: Evaluate the risk of an unauthenticated event. + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/ScoringRequest" + responses: + "200": + description: Verdict for the evaluated event. + content: + application/json: + schema: + $ref: "#/components/schemas/Verdict" + /log: + post: + operationId: log + tags: [Scoring] + summary: Log an event without scoring it. + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/ScoringRequest" + responses: + "200": + description: The logged event was accepted. + content: + application/json: + schema: + type: object + /lists: + get: + operationId: listAllLists + tags: [Lists] + summary: Return all lists. + responses: + "200": + description: The available lists. + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/List" + post: + operationId: createList + tags: [Lists] + summary: Create a list. + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/ListRequest" + responses: + "201": + description: The created list. + content: + application/json: + schema: + $ref: "#/components/schemas/List" + /privacy/users: + post: + operationId: requestUserData + tags: [Privacy] + summary: Request a data export for a user. + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/PrivacyRequest" + responses: + "200": + description: The privacy request was accepted. + content: + application/json: + schema: + type: object + delete: + operationId: deleteUserData + tags: [Privacy] + summary: Request deletion of a user's data. + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/PrivacyRequest" + responses: + "200": + description: The deletion request was accepted. + content: + application/json: + schema: + type: object + /events/schema: + get: + operationId: eventsSchema + tags: [Events] + summary: Return the event schema for the account. + responses: + "200": + description: The event schema. + content: + application/json: + schema: + type: object +components: + securitySchemes: + apiSecret: + type: http + scheme: basic + description: HTTP Basic auth with the API secret as the username and an empty password. + schemas: + ScoringRequest: + type: object + required: [type] + properties: + type: + type: string + example: "$login" + status: + type: string + example: "$succeeded" + request_token: + type: string + user: + $ref: "#/components/schemas/User" + properties: + type: object + additionalProperties: true + context: + type: object + additionalProperties: true + User: + type: object + properties: + id: + type: string + email: + type: string + name: + type: string + traits: + type: object + additionalProperties: true + Verdict: + type: object + properties: + risk: + type: number + format: double + policy: + $ref: "#/components/schemas/Policy" + signals: + type: object + additionalProperties: true + failover: + type: boolean + failover_reason: + type: string + Policy: + type: object + properties: + action: + type: string + enum: [allow, challenge, deny] + name: + type: string + id: + type: string + List: + type: object + properties: + id: + type: string + name: + type: string + color: + type: string + ListRequest: + type: object + required: [name] + properties: + name: + type: string + color: + type: string + PrivacyRequest: + type: object + required: [user_id] + properties: + user_id: + type: string