PRDCT-553: Generic Writer under Components › Writers (re-cut off main) - #1052
Open
Iamfle4ka wants to merge 3 commits into
Open
PRDCT-553: Generic Writer under Components › Writers (re-cut off main)#1052Iamfle4ka wants to merge 3 commits into
Iamfle4ka wants to merge 3 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This was referenced Aug 3, 2026
Iamfle4ka
force-pushed
the
PRDCT-553-generic-writer-recut
branch
from
August 4, 2026 23:40
42f4412 to
1cc2ddf
Compare
Re-cut of phase-2 batch 3 (was #1032, stacked on #1027) as a standalone per-unit PR off main, per the 2026-07-27 pivot. Moves the 3 Generic Writer pages to /components/writers/generic-writer/ (with the other data destination connectors). Old /extend/generic-writer/* URLs keep working via redirect_from. Build clean; audit 0 missing images. Broken links are forward-refs to /components/extractors/generic-extractor/ (batch PRDCT-552, not yet on main). Supersedes the stacked #1032 (closed with the #1027 stack once the queue drains). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ified facts
Deep-review pass on the Generic Writer page set (Jordan, 2026-07-29): every
claim checked against a source of truth before re-requesting review.
Source of truth: component id kds-team.wr-generic, repo
bitbucket.org/kds_consulting_team/kds-team.wr-generic (public, live) —
src/configuration.py (schema), src/component.py (placeholders/iteration),
src/json_converter.py, src/user_functions.py, src/http_generic/auth.py, and
the recorded functional examples under docs/examples/001-037.
Rendering blocker (introduced by the phase-1 migration):
- The inlined writer-config-map include produced "```json {" / "} ```", which
is not a valid CommonMark fence pair. The result was one 168-line code block
swallowing lines 66-233, so "## Api", "### Base URL" and "### Retry Config"
rendered as literal text and the #api / #base-url / #retry-config anchors
did not exist. Headings 34 -> 37; longest code block 168 -> 84 lines.
- Removed the 46-line jQuery <script> + <style> inlined from
writer-config-events.js. There is no jQuery in this repo, its
span:contains() selectors targeted Jekyll/Rouge markup (this site uses
Expressive Code), and 6 of its hardcoded anchors were wrong.
- Reworded the config-map lede, which promised a clickable map that the
removed script used to provide.
Claims refuted by the component source:
- autodetect default is false, not true (ColumnDataTypes.autodetect = False).
- Four datatypes, not "three" (DataType enum); dropped the "(three levels)"
nesting limit, which no code enforces.
- Dropped UPDATE from the supported methods: it is not an HTTP verb and the
list was copied from python-http-client's never-enforced ALLOWED_METHODS.
Noted that the method is passed through unvalidated.
- base_url / endpoint_path placeholders are filled from iteration columns
only, not from user_parameters; documented that a base_url placeholder
resolves once and is reused for later rows.
- EMPTY_REQUEST sends one request without iterate_by_columns, not one per row.
- Iteration mode does not override chunk_size to 1; chunk_size still controls
payload shape (proven by docs/examples/005's recorded array request).
- Dynamic functions also evaluate in headers and query_parameters.
- json_mapping's nesting_delimiter / chunk_size / column_data_types are all
required when the section is present.
- Stale key names: request_options -> request_parameters (x2),
column_types -> column_data_types.datatype_override.
- [[id]] is canonical; {{id}} documented as a legacy alias.
- bool conversion also accepts 0 / "0" as False.
- retry_config codes: dropped leaked Python tuple notation.
- Fixed address__streed -> address__street and its invalid JSON.
- chunk_size sample 1 -> 2 to match the prose and the shown output.
Examples:
- Removed Authorization headers referencing an undefined token_encoded from
the Iterations and Customer.io examples: an {"attr": ...} with no matching
user parameter is a hard validation failure, so both configs could not run.
- Added the required "user_parameters": {} to the Customer.io example, which
otherwise raises KeyError: 'user_parameters'. All 6 JSON blocks now parse.
- Content-type application/csv -> application/json where the body is JSON.
- Slack example debug: true -> false (it prints payloads into the job log).
- Stripped the trailing "?" from all 4 endpoint_path values (a v1 converter
artifact).
- Replaced leaked @keboola.com addresses, including a real employee address,
with the @test.com values from the input table.
Links, anchors and typos:
- #enpoint-path -> #endpoint-path; empty [dynamic functions]() href.
- Rotted third-party links: Exponea -> Bloomreach Engagement (note that
.../reference/batch-commands is a soft 404, so .../batch-commands-2 is
used), Customer.io -> docs.customer.io/integrations/api/track/,
strftime.org (now a 403 vendor page) -> docs.python.org.
- index.md: relative overview/encryption/ link, which has no help target yet,
now points at the live dev URL; trailing slash on the examples link;
"encripted" and 7 other inherited typos; 3 sections that described "default
query parameters" regardless of their actual subject.
- Cross-linked Generic Writer from the Writers hub and Other hub pages.
Verified: build clean (259 pages); audit-phase2 unclosed code fences 1 -> 0,
0 missing images, 0 malformed tables, broken links unchanged at 6 (the 3 from
these pages are the known forward-refs to the Generic Extractor batch, #1054);
all 29 self-anchors resolve; the rendered config map parses as valid JSON;
all 3 /extend/generic-writer/* redirects resolve.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Iamfle4ka
force-pushed
the
PRDCT-553-generic-writer-recut
branch
from
August 4, 2026 23:45
1cc2ddf to
e19ecf8
Compare
…riter-recut # Conflicts: # src/content/docs/components/writers/other/index.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Moves the 3 Generic Writer pages to
/components/writers/generic-writer/, alongside the other data destination connectors. Old/extend/generic-writer/*URLs keep working viaredirect_from.Re-cut of phase-2 batch 3 (was #1032, stacked on the big-bang #1027) as a standalone per-unit PR off
main, per the 2026-07-27 pivot.Deep-review pass (2026-07-29)
Per your "each deserves attention individually… I want every line scrutinized" — every claim on these pages was checked against a source of truth. The move itself was faithful (no dropped sections, mangled tables, or leftover Liquid), but it shipped a rendering blocker, and the pages inherited a batch of factual errors from the upstream README.
Source of truth used
kds-team.wr-generic(in-app name is just "Generic", typewriter, vendorkds-team)bitbucket.org/kds_consulting_team/kds-team.wr-generic— public and live (HTTP 200,master, updated 2025-02-13), so the ~29 Bitbucket links in these pages all still work. No GitHub mirror exists.src/configuration.pydataclasses. The Storage APIconfigurationSchemais{}— this component isgenericDockerUI, i.e. configured by raw JSON, which is why these pages are a JSON reference with no form-UI walkthrough.src/component.py,src/json_converter.py,src/user_functions.py,src/http_generic/auth.py, plus the recorded functional examples indocs/examples/001–0371. Rendering blocker (introduced by the phase-1 migration)
The inlined
writer-config-mapinclude produced```json {…} ```— not a valid CommonMark fence pair. One 168-line code block swallowed lines 66–233, so## Api,### Base URLand### Retry Configrendered as literal text and the#api/#base-url/#retry-configanchors did not exist (3 links in the config map pointed at them). Headings 34 → 37; longest code block 168 → 84 lines.Also removed the 46-line jQuery
<script>+<style>inlined fromwriter-config-events.js: there is no jQuery in this repo, itsspan:contains()selectors targeted Jekyll/Rouge markup (we render with Expressive Code), and 6 of its hardcoded anchors were wrong. Its purpose was to make the config map clickable, so I reworded the lede that promised that.2. Claims the component's own code refutes
All inherited from the dev original — each is provable from the source or from a recorded functional example:
autodetectdefault isfalse, nottrue.UPDATEfrom supported HTTP methods. It isn't an HTTP verb; the list was copied frompython-http-client'sALLOWED_METHODS, which is defined but never enforced. Noted that the method is passed through unvalidated.base_url/endpoint_pathplaceholders are filled from iteration columns only, not fromuser_parameters— the page said either would work, and contradicted itself two sections later. Also documented that abase_urlplaceholder resolves once and is then reused for every later row.EMPTY_REQUESTsends one request withoutiterate_by_columns, not one per row. As written, a 100-row table meant to fire 100 webhooks fires one.chunk_sizeto1;chunk_sizestill controls payload shape. Proven bydocs/examples/005, whose recorded request is an array.headersandquery_parameters, not onlyuser_parameters.json_mapping'snesting_delimiter/chunk_size/column_data_typesare all required when the section is present.request_options→request_parameters(×2),column_types→column_data_types.datatype_override.[[id]]is canonical;{{id}}is documented as a still-supported legacy alias (the code comment says so outright).boolconversion also accepts0/"0"asFalse.Plus: leaked Python tuple notation on
retry_config.codes,address__streed→address__streetwith its invalid JSON repaired, and achunk_sizesample that disagreed with both its prose and its own shown output.3. Two examples could not have run
Authorization: {"attr": "token_encoded"}while defining no such user parameter. That's a hard validation failure, so neither config worked. Removed (Customer.io already uses BasicHttp; Exponea and Slack legitimately definetoken_encodedand keep theirs).user_parametersentirely, which raisesKeyError: 'user_parameters'— the component indexes rather than.gets it, and every functional example ships"user_parameters": {}even when empty. Added.All 6 JSON blocks on the examples page now parse.
Also:
Content-type: application/csv→application/jsonwhere the body is JSON; Slack exampledebug: true→false(the page's own CAUTION warns it prints payloads into the job log); stripped the trailing?from all 4endpoint_pathvalues (a v1-converter artifact); and removed leaked@keboola.comaddresses, including a real employee's, replacing them with the@test.comvalues from the input table.4. Links and typos
#enpoint-path→#endpoint-path; an empty[dynamic functions]()href; the slashlessoverview/encryption/link; a missing trailing slash; "encripted" and 7 other inherited typos; and 3 sections that all described "default query parameters" regardless of their actual subject.Rotted third-party links repointed: Exponea → Bloomreach Engagement, Customer.io →⚠️ Note
docs.customer.io/integrations/api/track/, andstrftime.org(now a 403 vendor marketing page) →docs.python.org.documentation.bloomreach.com/engagement/reference/batch-commandsis a soft 404 — HTTP 200 with a not-found body — so the real page is…/batch-commands-2, verified by content.Verification
npm run buildclean — 259 pages.audit-phase2.mjsvs this branch's own pre-fix baseline: unclosed code fences 1 → 0, 0 missing images, 0 malformed tables, broken links unchanged at 6./extend/generic-writer/*redirects resolve. One<h1>per page.The 3 links to
/components/extractors/generic-extractor/**inindex.mdare deliberate forward-refs to the Generic Extractor batch (#1054), which creates all three targets including the## Generic Extractor Requirementsheading and thetutorial/json/page. Please merge #1054 before this PR, or those 3 links 404 on production.Open question for you
autodetect: falsemay not actually work, and the page still claims it makes unspecified columns strings. The pinned converter (csv2json0.5.7,hone_csv2json.py:73) hardcodesinfer_undefined=True, discarding the flag the writer passes down — so type inference appears to always be on, and a reader settingautodetect: falseto protect zip codes or phone numbers would still get numbers. That reads like a component bug, not a docs bug, so I left the text alone rather than assert it. Worth raising withkds-team.Deliberately out of scope
No screenshots, no "Create a new configuration" intro, and no documenting the real-but-undocumented options (
ApiKey/Login/OAuth20ClientCredentialsauth,continue_on_failure,md5_encode, the{"time": …}placeholders, theJSON_URL_ENCODEDchunk-size override). All recorded as follow-ups on PRDCT-553. Also filed there: the component's Developer PortaldocumentationUrlstill points atdevelopers.keboola.com/extend/generic-writer/configuration/and needs repointing by akds-teammaintainer before the dev domain 301s.Supersedes
Replaces the stacked #1032 (closed with the #1027 stack once the per-unit queue is drained).
🤖 Generated with Claude Code
Placement / dedup + regroup audit (2026-08-03)
Ran the placement/dedup pass (migration-placement skill). No duplication — there was no
existing Generic Writer page on
main, so this is net-new. Placed first-class under DataDestination Connectors (
components/writers/generic-writer/), parallel to how Generic Extractorwas placed. Component id
kds-team.wr-genericverified against the live catalog. No single-pagefix needed.
Regroup question for Jordan / Matias — Components ("use") vs Extending Keboola ("build")
[strong, spans several units]:
Generic Writer and Generic Extractor are build-your-own-connector tools, but they're filed on
the use side (under Components), while the build docs live in the separate top-level
Extending Keboola section — whose sub-node is also titled "Components". So there are two
nav nodes named "Components" and the build tools sit away from the build docs:
Recommendation: these tools are used both as ready connectors and as build primitives → lean
Option A (keep under Components + rename the duplicate "Components" node). Owner/Matias call.
Related: the Generic Extractor home question on #1054 (first-class vs inside "Other") is the same
family of decision. Not touched here — surfacing per Jordan's "formulate the question, ask Matias."