Repository files navigation

ApigenPythonCore

PythonPython >=3.13GitHub Release

apigen_copier is a Python package that generates backend project scaffolds from API contracts.

It is designed to be used as a dependency inside other Python projects that want to automate service creation from OpenAPI or AsyncAPI input. The generator reads a structured contract, applies Copier + Jinja templates, and creates a project skeleton that can later be extended by hand.

What this project is for

This repository is useful when you want to:

  • generate a Python service from an API-first contract
  • standardize the structure of generated projects across teams
  • bootstrap REST or event-driven services with less manual setup
  • regenerate a project without losing preserved custom code blocks

The generated output is focused on a layered Python backend structure, including domain models, infrastructure code, routes, services, repositories, mappers, and supporting files.

Main use cases

1. OpenAPI -> generated REST project

Use generate_project(...) when your input is an OpenAPI YAML or JSON file.

The package parses:

  • x-apigen-project for project-level configuration
  • components.x-apigen-models for domain/entity definitions
  • paths plus x-apigen-binding for route-to-model binding
  • components.schemas for request and response shapes

2. AsyncAPI -> generated event-driven project

Use generate_async_project(...) when your input is already parsed into a Python dict compatible with AsyncAPIProjectSchema.

This flow is intended for event-driven services and supports concepts such as:

  • brokers and servers
  • channels
  • operations
  • message payload schemas
  • entity definitions used during generation

Installation

Install with pip

pip install "git+https://gitlab.com/cloudappi/clo-innova/opendataspace/ods-data-generator-examples.git"

Add it to requirements.txt

git+https://gitlab.com/cloudappi/clo-innova/opendataspace/ods-data-generator-examples.git

Install from a local clone

pip install .

Public API

The package exposes these main entry points:

fromapigen_copierimport (
generate_project,
generate_from_schema,
generate_async_project,
generate_from_async_schema,
)

How to use it in another Python project

The most common integration is:

  1. Add apigen_copier as a dependency
  2. Store an API contract in your project
  3. Call the generator from a Python script, command, or build step
  4. Commit or process the generated output

Example:

fromapigen_copierimportgenerate_projectgenerate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
)

If you want to regenerate an existing generated project and preserve custom code blocks:

fromapigen_copierimportgenerate_projectgenerate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
existing_project_dir="generated/pet-service",
)

Expected input for OpenAPI generation

For generate_project(...), the input must be a YAML or JSON file.

If the file contains openapi or swagger, the package treats it as an OpenAPI specification and parses it automatically.

Minimum recommended structure

openapi: 3.0.0info:
title: Pet APIversion: 1.0.0x-apigen-project:
name: Pet Serviceversion: 1.0.0description: Service generated from OpenAPIdata-driver: postgresqlprefix: /api/v1paths:
/pets:
x-apigen-binding:
model: Petget:
operationId: listPetsresponses:
"200":
description: OKpost:
operationId: createPetrequestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/PetCreate"responses:
"201":
description: Created/pets/{id}:
x-apigen-binding:
model: Petget:
operationId: getPetByIdparameters:
- name: idin: pathrequired: trueschema:
type: stringresponses:
"200":
description: OKcontent:
application/json:
schema:
$ref: "#/components/schemas/PetGet"components:
x-apigen-models:
Pet:
relational-persistence:
table: petsattributes:
- name: idtype: Stringrelational-persistence:
primary-key: trueautogenerated: true
- name: nametype: String
- name: statustype: Stringschemas:
PetGet:
x-apigen-mapping:
model: Petmethod: gettype: objectproperties:
id:
type: stringname:
type: stringstatus:
type: stringPetCreate:
x-apigen-mapping:
model: Petmethod: posttype: objectproperties:
name:
type: stringstatus:
type: string

Input rules that matter

  • x-apigen-project defines the generated project metadata
  • components.x-apigen-models defines the domain models used by the generator
  • each model should define a primary key
  • only operations with x-apigen-binding are turned into generated routers
  • components.schemas is used to infer request and response models
  • data-driver currently accepts values such as postgresql, mysql, oracle, sqlite, mssql, and s3

Expected input for AsyncAPI generation

For generate_async_project(...), the input is a Python dict, not a raw file path.

At minimum, the dictionary should contain:

  • project
  • servers
  • channels
  • operations
  • entities
  • components

Example:

fromapigen_copierimportgenerate_async_projectparsed_data= {
"project": {
"name": "order-events-service",
"version": "1.0.0",
"description": "Async generated service",
"data-driver": "postgresql",
},
"servers": {
"kafka-dev": {
"host": "localhost:9092",
"protocol": "kafka",
"security": [],
}
},
"channels": {
"orderEvents": {
"address": "orders.events",
"parameters": {},
"messages": {},
}
},
"operations": {
"onOrderCreated": {
"action": "receive",
"channel": {
"address": "orders.events",
"parameters": {},
"messages": {},
},
"bindings": {"kafka": {"groupId": "order-service-group"}},
"reply": None,
"messages": [],
}
},
"entities": {
"Order": {
"table": "orders",
"attributes": [
{
"name": "id",
"type": "String",
"relational-persistence": {
"primary-key": True,
"autogenerated": False,
},
}
],
}
},
"components": {
"schemas": {}
},
}
generate_async_project(
parsed_data=parsed_data,
output_dir="generated/order-events-service",
)

What gets generated

Depending on the input and template, the package can generate files such as:

  • project scaffolding
  • domain models
  • route modules
  • repositories
  • services
  • mappers
  • broker configuration
  • DTOs and response models

Regeneration and custom code preservation

One of the important features of this package is regeneration support.

When existing_project_dir is provided, the generator can:

  • extract preserved custom code blocks from the previous project
  • inject them into the regenerated project
  • copy an existing UserCode/ folder into the new output

This makes the package suitable not only for one-time scaffolding, but also for iterative generation workflows.

Typical integration pattern

In a consuming repository, a common setup is:

my-python-project/
├── specs/
│ └── petstore.yaml
├── scripts/
│ └── generate_service.py
├── generated/
│ └── pet-service/
└── pyproject.toml or requirements.txt

Example generator script:

fromapigen_copierimportgenerate_projectdefmain() ->None:
generate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
)
if__name__=="__main__":
main()

Then run:

python scripts/generate_service.py

Summary

apigen_copier is a reusable Python dependency for teams that want to generate backend projects from API contracts instead of writing the initial boilerplate by hand. Its main value is that it turns structured API input into a maintainable project skeleton and supports safe regeneration when the contract evolves.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

ApigenPythonCore

PythonPython >=3.13GitHub Release

apigen_copier is a Python package that generates backend project scaffolds from API contracts.

It is designed to be used as a dependency inside other Python projects that want to automate service creation from OpenAPI or AsyncAPI input. The generator reads a structured contract, applies Copier + Jinja templates, and creates a project skeleton that can later be extended by hand.

What this project is for

This repository is useful when you want to:

  • generate a Python service from an API-first contract
  • standardize the structure of generated projects across teams
  • bootstrap REST or event-driven services with less manual setup
  • regenerate a project without losing preserved custom code blocks

The generated output is focused on a layered Python backend structure, including domain models, infrastructure code, routes, services, repositories, mappers, and supporting files.

Main use cases

1. OpenAPI -> generated REST project

Use generate_project(...) when your input is an OpenAPI YAML or JSON file.

The package parses:

  • x-apigen-project for project-level configuration
  • components.x-apigen-models for domain/entity definitions
  • paths plus x-apigen-binding for route-to-model binding
  • components.schemas for request and response shapes

2. AsyncAPI -> generated event-driven project

Use generate_async_project(...) when your input is already parsed into a Python dict compatible with AsyncAPIProjectSchema.

This flow is intended for event-driven services and supports concepts such as:

  • brokers and servers
  • channels
  • operations
  • message payload schemas
  • entity definitions used during generation

Installation

Install with pip

pip install "git+https://gitlab.com/cloudappi/clo-innova/opendataspace/ods-data-generator-examples.git"

Add it to requirements.txt

git+https://gitlab.com/cloudappi/clo-innova/opendataspace/ods-data-generator-examples.git

Install from a local clone

pip install .

Public API

The package exposes these main entry points:

fromapigen_copierimport (
generate_project,
generate_from_schema,
generate_async_project,
generate_from_async_schema,
)

How to use it in another Python project

The most common integration is:

  1. Add apigen_copier as a dependency
  2. Store an API contract in your project
  3. Call the generator from a Python script, command, or build step
  4. Commit or process the generated output

Example:

fromapigen_copierimportgenerate_projectgenerate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
)

If you want to regenerate an existing generated project and preserve custom code blocks:

fromapigen_copierimportgenerate_projectgenerate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
existing_project_dir="generated/pet-service",
)

Expected input for OpenAPI generation

For generate_project(...), the input must be a YAML or JSON file.

If the file contains openapi or swagger, the package treats it as an OpenAPI specification and parses it automatically.

Minimum recommended structure

openapi: 3.0.0info:
title: Pet APIversion: 1.0.0x-apigen-project:
name: Pet Serviceversion: 1.0.0description: Service generated from OpenAPIdata-driver: postgresqlprefix: /api/v1paths:
/pets:
x-apigen-binding:
model: Petget:
operationId: listPetsresponses:
"200":
description: OKpost:
operationId: createPetrequestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/PetCreate"responses:
"201":
description: Created/pets/{id}:
x-apigen-binding:
model: Petget:
operationId: getPetByIdparameters:
- name: idin: pathrequired: trueschema:
type: stringresponses:
"200":
description: OKcontent:
application/json:
schema:
$ref: "#/components/schemas/PetGet"components:
x-apigen-models:
Pet:
relational-persistence:
table: petsattributes:
- name: idtype: Stringrelational-persistence:
primary-key: trueautogenerated: true
- name: nametype: String
- name: statustype: Stringschemas:
PetGet:
x-apigen-mapping:
model: Petmethod: gettype: objectproperties:
id:
type: stringname:
type: stringstatus:
type: stringPetCreate:
x-apigen-mapping:
model: Petmethod: posttype: objectproperties:
name:
type: stringstatus:
type: string

Input rules that matter

  • x-apigen-project defines the generated project metadata
  • components.x-apigen-models defines the domain models used by the generator
  • each model should define a primary key
  • only operations with x-apigen-binding are turned into generated routers
  • components.schemas is used to infer request and response models
  • data-driver currently accepts values such as postgresql, mysql, oracle, sqlite, mssql, and s3

Expected input for AsyncAPI generation

For generate_async_project(...), the input is a Python dict, not a raw file path.

At minimum, the dictionary should contain:

  • project
  • servers
  • channels
  • operations
  • entities
  • components

Example:

fromapigen_copierimportgenerate_async_projectparsed_data= {
"project": {
"name": "order-events-service",
"version": "1.0.0",
"description": "Async generated service",
"data-driver": "postgresql",
},
"servers": {
"kafka-dev": {
"host": "localhost:9092",
"protocol": "kafka",
"security": [],
}
},
"channels": {
"orderEvents": {
"address": "orders.events",
"parameters": {},
"messages": {},
}
},
"operations": {
"onOrderCreated": {
"action": "receive",
"channel": {
"address": "orders.events",
"parameters": {},
"messages": {},
},
"bindings": {"kafka": {"groupId": "order-service-group"}},
"reply": None,
"messages": [],
}
},
"entities": {
"Order": {
"table": "orders",
"attributes": [
{
"name": "id",
"type": "String",
"relational-persistence": {
"primary-key": True,
"autogenerated": False,
},
}
],
}
},
"components": {
"schemas": {}
},
}
generate_async_project(
parsed_data=parsed_data,
output_dir="generated/order-events-service",
)

What gets generated

Depending on the input and template, the package can generate files such as:

  • project scaffolding
  • domain models
  • route modules
  • repositories
  • services
  • mappers
  • broker configuration
  • DTOs and response models

Regeneration and custom code preservation

One of the important features of this package is regeneration support.

When existing_project_dir is provided, the generator can:

  • extract preserved custom code blocks from the previous project
  • inject them into the regenerated project
  • copy an existing UserCode/ folder into the new output

This makes the package suitable not only for one-time scaffolding, but also for iterative generation workflows.

Typical integration pattern

In a consuming repository, a common setup is:

my-python-project/
├── specs/
│ └── petstore.yaml
├── scripts/
│ └── generate_service.py
├── generated/
│ └── pet-service/
└── pyproject.toml or requirements.txt

Example generator script:

fromapigen_copierimportgenerate_projectdefmain() ->None:
generate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
)
if__name__=="__main__":
main()

Then run:

python scripts/generate_service.py

Summary

apigen_copier is a reusable Python dependency for teams that want to generate backend projects from API contracts instead of writing the initial boilerplate by hand. Its main value is that it turns structured API input into a maintainable project skeleton and supports safe regeneration when the contract evolves.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ApigenPythonCore

PythonPython >=3.13GitHub Release

apigen_copier is a Python package that generates backend project scaffolds from API contracts.

It is designed to be used as a dependency inside other Python projects that want to automate service creation from OpenAPI or AsyncAPI input. The generator reads a structured contract, applies Copier + Jinja templates, and creates a project skeleton that can later be extended by hand.

What this project is for

This repository is useful when you want to:

  • generate a Python service from an API-first contract
  • standardize the structure of generated projects across teams
  • bootstrap REST or event-driven services with less manual setup
  • regenerate a project without losing preserved custom code blocks

The generated output is focused on a layered Python backend structure, including domain models, infrastructure code, routes, services, repositories, mappers, and supporting files.

Main use cases

1. OpenAPI -> generated REST project

Use generate_project(...) when your input is an OpenAPI YAML or JSON file.

The package parses:

  • x-apigen-project for project-level configuration
  • components.x-apigen-models for domain/entity definitions
  • paths plus x-apigen-binding for route-to-model binding
  • components.schemas for request and response shapes

2. AsyncAPI -> generated event-driven project

Use generate_async_project(...) when your input is already parsed into a Python dict compatible with AsyncAPIProjectSchema.

This flow is intended for event-driven services and supports concepts such as:

  • brokers and servers
  • channels
  • operations
  • message payload schemas
  • entity definitions used during generation

Installation

Install with pip

pip install "git+https://gitlab.com/cloudappi/clo-innova/opendataspace/ods-data-generator-examples.git"

Add it to requirements.txt

git+https://gitlab.com/cloudappi/clo-innova/opendataspace/ods-data-generator-examples.git

Install from a local clone

pip install .

Public API

The package exposes these main entry points:

fromapigen_copierimport (
generate_project,
generate_from_schema,
generate_async_project,
generate_from_async_schema,
)

How to use it in another Python project

The most common integration is:

  1. Add apigen_copier as a dependency
  2. Store an API contract in your project
  3. Call the generator from a Python script, command, or build step
  4. Commit or process the generated output

Example:

fromapigen_copierimportgenerate_projectgenerate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
)

If you want to regenerate an existing generated project and preserve custom code blocks:

fromapigen_copierimportgenerate_projectgenerate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
existing_project_dir="generated/pet-service",
)

Expected input for OpenAPI generation

For generate_project(...), the input must be a YAML or JSON file.

If the file contains openapi or swagger, the package treats it as an OpenAPI specification and parses it automatically.

Minimum recommended structure

openapi: 3.0.0info:
title: Pet APIversion: 1.0.0x-apigen-project:
name: Pet Serviceversion: 1.0.0description: Service generated from OpenAPIdata-driver: postgresqlprefix: /api/v1paths:
/pets:
x-apigen-binding:
model: Petget:
operationId: listPetsresponses:
"200":
description: OKpost:
operationId: createPetrequestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/PetCreate"responses:
"201":
description: Created/pets/{id}:
x-apigen-binding:
model: Petget:
operationId: getPetByIdparameters:
- name: idin: pathrequired: trueschema:
type: stringresponses:
"200":
description: OKcontent:
application/json:
schema:
$ref: "#/components/schemas/PetGet"components:
x-apigen-models:
Pet:
relational-persistence:
table: petsattributes:
- name: idtype: Stringrelational-persistence:
primary-key: trueautogenerated: true
- name: nametype: String
- name: statustype: Stringschemas:
PetGet:
x-apigen-mapping:
model: Petmethod: gettype: objectproperties:
id:
type: stringname:
type: stringstatus:
type: stringPetCreate:
x-apigen-mapping:
model: Petmethod: posttype: objectproperties:
name:
type: stringstatus:
type: string

Input rules that matter

  • x-apigen-project defines the generated project metadata
  • components.x-apigen-models defines the domain models used by the generator
  • each model should define a primary key
  • only operations with x-apigen-binding are turned into generated routers
  • components.schemas is used to infer request and response models
  • data-driver currently accepts values such as postgresql, mysql, oracle, sqlite, mssql, and s3

Expected input for AsyncAPI generation

For generate_async_project(...), the input is a Python dict, not a raw file path.

At minimum, the dictionary should contain:

  • project
  • servers
  • channels
  • operations
  • entities
  • components

Example:

fromapigen_copierimportgenerate_async_projectparsed_data= {
"project": {
"name": "order-events-service",
"version": "1.0.0",
"description": "Async generated service",
"data-driver": "postgresql",
},
"servers": {
"kafka-dev": {
"host": "localhost:9092",
"protocol": "kafka",
"security": [],
}
},
"channels": {
"orderEvents": {
"address": "orders.events",
"parameters": {},
"messages": {},
}
},
"operations": {
"onOrderCreated": {
"action": "receive",
"channel": {
"address": "orders.events",
"parameters": {},
"messages": {},
},
"bindings": {"kafka": {"groupId": "order-service-group"}},
"reply": None,
"messages": [],
}
},
"entities": {
"Order": {
"table": "orders",
"attributes": [
{
"name": "id",
"type": "String",
"relational-persistence": {
"primary-key": True,
"autogenerated": False,
},
}
],
}
},
"components": {
"schemas": {}
},
}
generate_async_project(
parsed_data=parsed_data,
output_dir="generated/order-events-service",
)

What gets generated

Depending on the input and template, the package can generate files such as:

  • project scaffolding
  • domain models
  • route modules
  • repositories
  • services
  • mappers
  • broker configuration
  • DTOs and response models

Regeneration and custom code preservation

One of the important features of this package is regeneration support.

When existing_project_dir is provided, the generator can:

  • extract preserved custom code blocks from the previous project
  • inject them into the regenerated project
  • copy an existing UserCode/ folder into the new output

This makes the package suitable not only for one-time scaffolding, but also for iterative generation workflows.

Typical integration pattern

In a consuming repository, a common setup is:

my-python-project/
├── specs/
│ └── petstore.yaml
├── scripts/
│ └── generate_service.py
├── generated/
│ └── pet-service/
└── pyproject.toml or requirements.txt

Example generator script:

fromapigen_copierimportgenerate_projectdefmain() ->None:
generate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
)
if__name__=="__main__":
main()

Then run:

python scripts/generate_service.py

Summary

apigen_copier is a reusable Python dependency for teams that want to generate backend projects from API contracts instead of writing the initial boilerplate by hand. Its main value is that it turns structured API input into a maintainable project skeleton and supports safe regeneration when the contract evolves.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ApigenPythonCore

PythonPython >=3.13GitHub Release

apigen_copier is a Python package that generates backend project scaffolds from API contracts.

It is designed to be used as a dependency inside other Python projects that want to automate service creation from OpenAPI or AsyncAPI input. The generator reads a structured contract, applies Copier + Jinja templates, and creates a project skeleton that can later be extended by hand.

What this project is for

This repository is useful when you want to:

  • generate a Python service from an API-first contract
  • standardize the structure of generated projects across teams
  • bootstrap REST or event-driven services with less manual setup
  • regenerate a project without losing preserved custom code blocks

The generated output is focused on a layered Python backend structure, including domain models, infrastructure code, routes, services, repositories, mappers, and supporting files.

Main use cases

1. OpenAPI -> generated REST project

Use generate_project(...) when your input is an OpenAPI YAML or JSON file.

The package parses:

  • x-apigen-project for project-level configuration
  • components.x-apigen-models for domain/entity definitions
  • paths plus x-apigen-binding for route-to-model binding
  • components.schemas for request and response shapes

2. AsyncAPI -> generated event-driven project

Use generate_async_project(...) when your input is already parsed into a Python dict compatible with AsyncAPIProjectSchema.

This flow is intended for event-driven services and supports concepts such as:

  • brokers and servers
  • channels
  • operations
  • message payload schemas
  • entity definitions used during generation

Installation

Install with pip

pip install "git+https://gitlab.com/cloudappi/clo-innova/opendataspace/ods-data-generator-examples.git"

Add it to requirements.txt

git+https://gitlab.com/cloudappi/clo-innova/opendataspace/ods-data-generator-examples.git

Install from a local clone

pip install .

Public API

The package exposes these main entry points:

fromapigen_copierimport (
generate_project,
generate_from_schema,
generate_async_project,
generate_from_async_schema,
)

How to use it in another Python project

The most common integration is:

  1. Add apigen_copier as a dependency
  2. Store an API contract in your project
  3. Call the generator from a Python script, command, or build step
  4. Commit or process the generated output

Example:

fromapigen_copierimportgenerate_projectgenerate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
)

If you want to regenerate an existing generated project and preserve custom code blocks:

fromapigen_copierimportgenerate_projectgenerate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
existing_project_dir="generated/pet-service",
)

Expected input for OpenAPI generation

For generate_project(...), the input must be a YAML or JSON file.

If the file contains openapi or swagger, the package treats it as an OpenAPI specification and parses it automatically.

Minimum recommended structure

openapi: 3.0.0info:
title: Pet APIversion: 1.0.0x-apigen-project:
name: Pet Serviceversion: 1.0.0description: Service generated from OpenAPIdata-driver: postgresqlprefix: /api/v1paths:
/pets:
x-apigen-binding:
model: Petget:
operationId: listPetsresponses:
"200":
description: OKpost:
operationId: createPetrequestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/PetCreate"responses:
"201":
description: Created/pets/{id}:
x-apigen-binding:
model: Petget:
operationId: getPetByIdparameters:
- name: idin: pathrequired: trueschema:
type: stringresponses:
"200":
description: OKcontent:
application/json:
schema:
$ref: "#/components/schemas/PetGet"components:
x-apigen-models:
Pet:
relational-persistence:
table: petsattributes:
- name: idtype: Stringrelational-persistence:
primary-key: trueautogenerated: true
- name: nametype: String
- name: statustype: Stringschemas:
PetGet:
x-apigen-mapping:
model: Petmethod: gettype: objectproperties:
id:
type: stringname:
type: stringstatus:
type: stringPetCreate:
x-apigen-mapping:
model: Petmethod: posttype: objectproperties:
name:
type: stringstatus:
type: string

Input rules that matter

  • x-apigen-project defines the generated project metadata
  • components.x-apigen-models defines the domain models used by the generator
  • each model should define a primary key
  • only operations with x-apigen-binding are turned into generated routers
  • components.schemas is used to infer request and response models
  • data-driver currently accepts values such as postgresql, mysql, oracle, sqlite, mssql, and s3

Expected input for AsyncAPI generation

For generate_async_project(...), the input is a Python dict, not a raw file path.

At minimum, the dictionary should contain:

  • project
  • servers
  • channels
  • operations
  • entities
  • components

Example:

fromapigen_copierimportgenerate_async_projectparsed_data= {
"project": {
"name": "order-events-service",
"version": "1.0.0",
"description": "Async generated service",
"data-driver": "postgresql",
},
"servers": {
"kafka-dev": {
"host": "localhost:9092",
"protocol": "kafka",
"security": [],
}
},
"channels": {
"orderEvents": {
"address": "orders.events",
"parameters": {},
"messages": {},
}
},
"operations": {
"onOrderCreated": {
"action": "receive",
"channel": {
"address": "orders.events",
"parameters": {},
"messages": {},
},
"bindings": {"kafka": {"groupId": "order-service-group"}},
"reply": None,
"messages": [],
}
},
"entities": {
"Order": {
"table": "orders",
"attributes": [
{
"name": "id",
"type": "String",
"relational-persistence": {
"primary-key": True,
"autogenerated": False,
},
}
],
}
},
"components": {
"schemas": {}
},
}
generate_async_project(
parsed_data=parsed_data,
output_dir="generated/order-events-service",
)

What gets generated

Depending on the input and template, the package can generate files such as:

  • project scaffolding
  • domain models
  • route modules
  • repositories
  • services
  • mappers
  • broker configuration
  • DTOs and response models

Regeneration and custom code preservation

One of the important features of this package is regeneration support.

When existing_project_dir is provided, the generator can:

  • extract preserved custom code blocks from the previous project
  • inject them into the regenerated project
  • copy an existing UserCode/ folder into the new output

This makes the package suitable not only for one-time scaffolding, but also for iterative generation workflows.

Typical integration pattern

In a consuming repository, a common setup is:

my-python-project/
├── specs/
│ └── petstore.yaml
├── scripts/
│ └── generate_service.py
├── generated/
│ └── pet-service/
└── pyproject.toml or requirements.txt

Example generator script:

fromapigen_copierimportgenerate_projectdefmain() ->None:
generate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
)
if__name__=="__main__":
main()

Then run:

python scripts/generate_service.py

Summary

apigen_copier is a reusable Python dependency for teams that want to generate backend projects from API contracts instead of writing the initial boilerplate by hand. Its main value is that it turns structured API input into a maintainable project skeleton and supports safe regeneration when the contract evolves.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

ApigenPythonCore

PythonPython >=3.13GitHub Release

apigen_copier is a Python package that generates backend project scaffolds from API contracts.

It is designed to be used as a dependency inside other Python projects that want to automate service creation from OpenAPI or AsyncAPI input. The generator reads a structured contract, applies Copier + Jinja templates, and creates a project skeleton that can later be extended by hand.

What this project is for

This repository is useful when you want to:

  • generate a Python service from an API-first contract
  • standardize the structure of generated projects across teams
  • bootstrap REST or event-driven services with less manual setup
  • regenerate a project without losing preserved custom code blocks

The generated output is focused on a layered Python backend structure, including domain models, infrastructure code, routes, services, repositories, mappers, and supporting files.

Main use cases

1. OpenAPI -> generated REST project

Use generate_project(...) when your input is an OpenAPI YAML or JSON file.

The package parses:

  • x-apigen-project for project-level configuration
  • components.x-apigen-models for domain/entity definitions
  • paths plus x-apigen-binding for route-to-model binding
  • components.schemas for request and response shapes

2. AsyncAPI -> generated event-driven project

Use generate_async_project(...) when your input is already parsed into a Python dict compatible with AsyncAPIProjectSchema.

This flow is intended for event-driven services and supports concepts such as:

  • brokers and servers
  • channels
  • operations
  • message payload schemas
  • entity definitions used during generation

Installation

Install with pip

pip install "git+https://gitlab.com/cloudappi/clo-innova/opendataspace/ods-data-generator-examples.git"

Add it to requirements.txt

git+https://gitlab.com/cloudappi/clo-innova/opendataspace/ods-data-generator-examples.git

Install from a local clone

pip install .

Public API

The package exposes these main entry points:

fromapigen_copierimport (
generate_project,
generate_from_schema,
generate_async_project,
generate_from_async_schema,
)

How to use it in another Python project

The most common integration is:

  1. Add apigen_copier as a dependency
  2. Store an API contract in your project
  3. Call the generator from a Python script, command, or build step
  4. Commit or process the generated output

Example:

fromapigen_copierimportgenerate_projectgenerate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
)

If you want to regenerate an existing generated project and preserve custom code blocks:

fromapigen_copierimportgenerate_projectgenerate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
existing_project_dir="generated/pet-service",
)

Expected input for OpenAPI generation

For generate_project(...), the input must be a YAML or JSON file.

If the file contains openapi or swagger, the package treats it as an OpenAPI specification and parses it automatically.

Minimum recommended structure

openapi: 3.0.0info:
title: Pet APIversion: 1.0.0x-apigen-project:
name: Pet Serviceversion: 1.0.0description: Service generated from OpenAPIdata-driver: postgresqlprefix: /api/v1paths:
/pets:
x-apigen-binding:
model: Petget:
operationId: listPetsresponses:
"200":
description: OKpost:
operationId: createPetrequestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/PetCreate"responses:
"201":
description: Created/pets/{id}:
x-apigen-binding:
model: Petget:
operationId: getPetByIdparameters:
- name: idin: pathrequired: trueschema:
type: stringresponses:
"200":
description: OKcontent:
application/json:
schema:
$ref: "#/components/schemas/PetGet"components:
x-apigen-models:
Pet:
relational-persistence:
table: petsattributes:
- name: idtype: Stringrelational-persistence:
primary-key: trueautogenerated: true
- name: nametype: String
- name: statustype: Stringschemas:
PetGet:
x-apigen-mapping:
model: Petmethod: gettype: objectproperties:
id:
type: stringname:
type: stringstatus:
type: stringPetCreate:
x-apigen-mapping:
model: Petmethod: posttype: objectproperties:
name:
type: stringstatus:
type: string

Input rules that matter

  • x-apigen-project defines the generated project metadata
  • components.x-apigen-models defines the domain models used by the generator
  • each model should define a primary key
  • only operations with x-apigen-binding are turned into generated routers
  • components.schemas is used to infer request and response models
  • data-driver currently accepts values such as postgresql, mysql, oracle, sqlite, mssql, and s3

Expected input for AsyncAPI generation

For generate_async_project(...), the input is a Python dict, not a raw file path.

At minimum, the dictionary should contain:

  • project
  • servers
  • channels
  • operations
  • entities
  • components

Example:

fromapigen_copierimportgenerate_async_projectparsed_data= {
"project": {
"name": "order-events-service",
"version": "1.0.0",
"description": "Async generated service",
"data-driver": "postgresql",
},
"servers": {
"kafka-dev": {
"host": "localhost:9092",
"protocol": "kafka",
"security": [],
}
},
"channels": {
"orderEvents": {
"address": "orders.events",
"parameters": {},
"messages": {},
}
},
"operations": {
"onOrderCreated": {
"action": "receive",
"channel": {
"address": "orders.events",
"parameters": {},
"messages": {},
},
"bindings": {"kafka": {"groupId": "order-service-group"}},
"reply": None,
"messages": [],
}
},
"entities": {
"Order": {
"table": "orders",
"attributes": [
{
"name": "id",
"type": "String",
"relational-persistence": {
"primary-key": True,
"autogenerated": False,
},
}
],
}
},
"components": {
"schemas": {}
},
}
generate_async_project(
parsed_data=parsed_data,
output_dir="generated/order-events-service",
)

What gets generated

Depending on the input and template, the package can generate files such as:

  • project scaffolding
  • domain models
  • route modules
  • repositories
  • services
  • mappers
  • broker configuration
  • DTOs and response models

Regeneration and custom code preservation

One of the important features of this package is regeneration support.

When existing_project_dir is provided, the generator can:

  • extract preserved custom code blocks from the previous project
  • inject them into the regenerated project
  • copy an existing UserCode/ folder into the new output

This makes the package suitable not only for one-time scaffolding, but also for iterative generation workflows.

Typical integration pattern

In a consuming repository, a common setup is:

my-python-project/
├── specs/
│ └── petstore.yaml
├── scripts/
│ └── generate_service.py
├── generated/
│ └── pet-service/
└── pyproject.toml or requirements.txt

Example generator script:

fromapigen_copierimportgenerate_projectdefmain() ->None:
generate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
)
if__name__=="__main__":
main()

Then run:

python scripts/generate_service.py

Summary

apigen_copier is a reusable Python dependency for teams that want to generate backend projects from API contracts instead of writing the initial boilerplate by hand. Its main value is that it turns structured API input into a maintainable project skeleton and supports safe regeneration when the contract evolves.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ApigenPythonCore

PythonPython >=3.13GitHub Release

apigen_copier is a Python package that generates backend project scaffolds from API contracts.

It is designed to be used as a dependency inside other Python projects that want to automate service creation from OpenAPI or AsyncAPI input. The generator reads a structured contract, applies Copier + Jinja templates, and creates a project skeleton that can later be extended by hand.

What this project is for

This repository is useful when you want to:

  • generate a Python service from an API-first contract
  • standardize the structure of generated projects across teams
  • bootstrap REST or event-driven services with less manual setup
  • regenerate a project without losing preserved custom code blocks

The generated output is focused on a layered Python backend structure, including domain models, infrastructure code, routes, services, repositories, mappers, and supporting files.

Main use cases

1. OpenAPI -> generated REST project

Use generate_project(...) when your input is an OpenAPI YAML or JSON file.

The package parses:

  • x-apigen-project for project-level configuration
  • components.x-apigen-models for domain/entity definitions
  • paths plus x-apigen-binding for route-to-model binding
  • components.schemas for request and response shapes

2. AsyncAPI -> generated event-driven project

Use generate_async_project(...) when your input is already parsed into a Python dict compatible with AsyncAPIProjectSchema.

This flow is intended for event-driven services and supports concepts such as:

  • brokers and servers
  • channels
  • operations
  • message payload schemas
  • entity definitions used during generation

Installation

Install with pip

pip install "git+https://gitlab.com/cloudappi/clo-innova/opendataspace/ods-data-generator-examples.git"

Add it to requirements.txt

git+https://gitlab.com/cloudappi/clo-innova/opendataspace/ods-data-generator-examples.git

Install from a local clone

pip install .

Public API

The package exposes these main entry points:

fromapigen_copierimport (
generate_project,
generate_from_schema,
generate_async_project,
generate_from_async_schema,
)

How to use it in another Python project

The most common integration is:

  1. Add apigen_copier as a dependency
  2. Store an API contract in your project
  3. Call the generator from a Python script, command, or build step
  4. Commit or process the generated output

Example:

fromapigen_copierimportgenerate_projectgenerate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
)

If you want to regenerate an existing generated project and preserve custom code blocks:

fromapigen_copierimportgenerate_projectgenerate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
existing_project_dir="generated/pet-service",
)

Expected input for OpenAPI generation

For generate_project(...), the input must be a YAML or JSON file.

If the file contains openapi or swagger, the package treats it as an OpenAPI specification and parses it automatically.

Minimum recommended structure

openapi: 3.0.0info:
title: Pet APIversion: 1.0.0x-apigen-project:
name: Pet Serviceversion: 1.0.0description: Service generated from OpenAPIdata-driver: postgresqlprefix: /api/v1paths:
/pets:
x-apigen-binding:
model: Petget:
operationId: listPetsresponses:
"200":
description: OKpost:
operationId: createPetrequestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/PetCreate"responses:
"201":
description: Created/pets/{id}:
x-apigen-binding:
model: Petget:
operationId: getPetByIdparameters:
- name: idin: pathrequired: trueschema:
type: stringresponses:
"200":
description: OKcontent:
application/json:
schema:
$ref: "#/components/schemas/PetGet"components:
x-apigen-models:
Pet:
relational-persistence:
table: petsattributes:
- name: idtype: Stringrelational-persistence:
primary-key: trueautogenerated: true
- name: nametype: String
- name: statustype: Stringschemas:
PetGet:
x-apigen-mapping:
model: Petmethod: gettype: objectproperties:
id:
type: stringname:
type: stringstatus:
type: stringPetCreate:
x-apigen-mapping:
model: Petmethod: posttype: objectproperties:
name:
type: stringstatus:
type: string

Input rules that matter

  • x-apigen-project defines the generated project metadata
  • components.x-apigen-models defines the domain models used by the generator
  • each model should define a primary key
  • only operations with x-apigen-binding are turned into generated routers
  • components.schemas is used to infer request and response models
  • data-driver currently accepts values such as postgresql, mysql, oracle, sqlite, mssql, and s3

Expected input for AsyncAPI generation

For generate_async_project(...), the input is a Python dict, not a raw file path.

At minimum, the dictionary should contain:

  • project
  • servers
  • channels
  • operations
  • entities
  • components

Example:

fromapigen_copierimportgenerate_async_projectparsed_data= {
"project": {
"name": "order-events-service",
"version": "1.0.0",
"description": "Async generated service",
"data-driver": "postgresql",
},
"servers": {
"kafka-dev": {
"host": "localhost:9092",
"protocol": "kafka",
"security": [],
}
},
"channels": {
"orderEvents": {
"address": "orders.events",
"parameters": {},
"messages": {},
}
},
"operations": {
"onOrderCreated": {
"action": "receive",
"channel": {
"address": "orders.events",
"parameters": {},
"messages": {},
},
"bindings": {"kafka": {"groupId": "order-service-group"}},
"reply": None,
"messages": [],
}
},
"entities": {
"Order": {
"table": "orders",
"attributes": [
{
"name": "id",
"type": "String",
"relational-persistence": {
"primary-key": True,
"autogenerated": False,
},
}
],
}
},
"components": {
"schemas": {}
},
}
generate_async_project(
parsed_data=parsed_data,
output_dir="generated/order-events-service",
)

What gets generated

Depending on the input and template, the package can generate files such as:

  • project scaffolding
  • domain models
  • route modules
  • repositories
  • services
  • mappers
  • broker configuration
  • DTOs and response models

Regeneration and custom code preservation

One of the important features of this package is regeneration support.

When existing_project_dir is provided, the generator can:

  • extract preserved custom code blocks from the previous project
  • inject them into the regenerated project
  • copy an existing UserCode/ folder into the new output

This makes the package suitable not only for one-time scaffolding, but also for iterative generation workflows.

Typical integration pattern

In a consuming repository, a common setup is:

my-python-project/
├── specs/
│ └── petstore.yaml
├── scripts/
│ └── generate_service.py
├── generated/
│ └── pet-service/
└── pyproject.toml or requirements.txt

Example generator script:

fromapigen_copierimportgenerate_projectdefmain() ->None:
generate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
)
if__name__=="__main__":
main()

Then run:

python scripts/generate_service.py

Summary

apigen_copier is a reusable Python dependency for teams that want to generate backend projects from API contracts instead of writing the initial boilerplate by hand. Its main value is that it turns structured API input into a maintainable project skeleton and supports safe regeneration when the contract evolves.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ApigenPythonCore

PythonPython >=3.13GitHub Release

apigen_copier is a Python package that generates backend project scaffolds from API contracts.

It is designed to be used as a dependency inside other Python projects that want to automate service creation from OpenAPI or AsyncAPI input. The generator reads a structured contract, applies Copier + Jinja templates, and creates a project skeleton that can later be extended by hand.

What this project is for

This repository is useful when you want to:

  • generate a Python service from an API-first contract
  • standardize the structure of generated projects across teams
  • bootstrap REST or event-driven services with less manual setup
  • regenerate a project without losing preserved custom code blocks

The generated output is focused on a layered Python backend structure, including domain models, infrastructure code, routes, services, repositories, mappers, and supporting files.

Main use cases

1. OpenAPI -> generated REST project

Use generate_project(...) when your input is an OpenAPI YAML or JSON file.

The package parses:

  • x-apigen-project for project-level configuration
  • components.x-apigen-models for domain/entity definitions
  • paths plus x-apigen-binding for route-to-model binding
  • components.schemas for request and response shapes

2. AsyncAPI -> generated event-driven project

Use generate_async_project(...) when your input is already parsed into a Python dict compatible with AsyncAPIProjectSchema.

This flow is intended for event-driven services and supports concepts such as:

  • brokers and servers
  • channels
  • operations
  • message payload schemas
  • entity definitions used during generation

Installation

Install with pip

pip install "git+https://gitlab.com/cloudappi/clo-innova/opendataspace/ods-data-generator-examples.git"

Add it to requirements.txt

git+https://gitlab.com/cloudappi/clo-innova/opendataspace/ods-data-generator-examples.git

Install from a local clone

pip install .

Public API

The package exposes these main entry points:

fromapigen_copierimport (
generate_project,
generate_from_schema,
generate_async_project,
generate_from_async_schema,
)

How to use it in another Python project

The most common integration is:

  1. Add apigen_copier as a dependency
  2. Store an API contract in your project
  3. Call the generator from a Python script, command, or build step
  4. Commit or process the generated output

Example:

fromapigen_copierimportgenerate_projectgenerate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
)

If you want to regenerate an existing generated project and preserve custom code blocks:

fromapigen_copierimportgenerate_projectgenerate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
existing_project_dir="generated/pet-service",
)

Expected input for OpenAPI generation

For generate_project(...), the input must be a YAML or JSON file.

If the file contains openapi or swagger, the package treats it as an OpenAPI specification and parses it automatically.

Minimum recommended structure

openapi: 3.0.0info:
title: Pet APIversion: 1.0.0x-apigen-project:
name: Pet Serviceversion: 1.0.0description: Service generated from OpenAPIdata-driver: postgresqlprefix: /api/v1paths:
/pets:
x-apigen-binding:
model: Petget:
operationId: listPetsresponses:
"200":
description: OKpost:
operationId: createPetrequestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/PetCreate"responses:
"201":
description: Created/pets/{id}:
x-apigen-binding:
model: Petget:
operationId: getPetByIdparameters:
- name: idin: pathrequired: trueschema:
type: stringresponses:
"200":
description: OKcontent:
application/json:
schema:
$ref: "#/components/schemas/PetGet"components:
x-apigen-models:
Pet:
relational-persistence:
table: petsattributes:
- name: idtype: Stringrelational-persistence:
primary-key: trueautogenerated: true
- name: nametype: String
- name: statustype: Stringschemas:
PetGet:
x-apigen-mapping:
model: Petmethod: gettype: objectproperties:
id:
type: stringname:
type: stringstatus:
type: stringPetCreate:
x-apigen-mapping:
model: Petmethod: posttype: objectproperties:
name:
type: stringstatus:
type: string

Input rules that matter

  • x-apigen-project defines the generated project metadata
  • components.x-apigen-models defines the domain models used by the generator
  • each model should define a primary key
  • only operations with x-apigen-binding are turned into generated routers
  • components.schemas is used to infer request and response models
  • data-driver currently accepts values such as postgresql, mysql, oracle, sqlite, mssql, and s3

Expected input for AsyncAPI generation

For generate_async_project(...), the input is a Python dict, not a raw file path.

At minimum, the dictionary should contain:

  • project
  • servers
  • channels
  • operations
  • entities
  • components

Example:

fromapigen_copierimportgenerate_async_projectparsed_data= {
"project": {
"name": "order-events-service",
"version": "1.0.0",
"description": "Async generated service",
"data-driver": "postgresql",
},
"servers": {
"kafka-dev": {
"host": "localhost:9092",
"protocol": "kafka",
"security": [],
}
},
"channels": {
"orderEvents": {
"address": "orders.events",
"parameters": {},
"messages": {},
}
},
"operations": {
"onOrderCreated": {
"action": "receive",
"channel": {
"address": "orders.events",
"parameters": {},
"messages": {},
},
"bindings": {"kafka": {"groupId": "order-service-group"}},
"reply": None,
"messages": [],
}
},
"entities": {
"Order": {
"table": "orders",
"attributes": [
{
"name": "id",
"type": "String",
"relational-persistence": {
"primary-key": True,
"autogenerated": False,
},
}
],
}
},
"components": {
"schemas": {}
},
}
generate_async_project(
parsed_data=parsed_data,
output_dir="generated/order-events-service",
)

What gets generated

Depending on the input and template, the package can generate files such as:

  • project scaffolding
  • domain models
  • route modules
  • repositories
  • services
  • mappers
  • broker configuration
  • DTOs and response models

Regeneration and custom code preservation

One of the important features of this package is regeneration support.

When existing_project_dir is provided, the generator can:

  • extract preserved custom code blocks from the previous project
  • inject them into the regenerated project
  • copy an existing UserCode/ folder into the new output

This makes the package suitable not only for one-time scaffolding, but also for iterative generation workflows.

Typical integration pattern

In a consuming repository, a common setup is:

my-python-project/
├── specs/
│ └── petstore.yaml
├── scripts/
│ └── generate_service.py
├── generated/
│ └── pet-service/
└── pyproject.toml or requirements.txt

Example generator script:

fromapigen_copierimportgenerate_projectdefmain() ->None:
generate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
)
if__name__=="__main__":
main()

Then run:

python scripts/generate_service.py

Summary

apigen_copier is a reusable Python dependency for teams that want to generate backend projects from API contracts instead of writing the initial boilerplate by hand. Its main value is that it turns structured API input into a maintainable project skeleton and supports safe regeneration when the contract evolves.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

ApigenPythonCore

PythonPython >=3.13GitHub Release

apigen_copier is a Python package that generates backend project scaffolds from API contracts.

It is designed to be used as a dependency inside other Python projects that want to automate service creation from OpenAPI or AsyncAPI input. The generator reads a structured contract, applies Copier + Jinja templates, and creates a project skeleton that can later be extended by hand.

What this project is for

This repository is useful when you want to:

  • generate a Python service from an API-first contract
  • standardize the structure of generated projects across teams
  • bootstrap REST or event-driven services with less manual setup
  • regenerate a project without losing preserved custom code blocks

The generated output is focused on a layered Python backend structure, including domain models, infrastructure code, routes, services, repositories, mappers, and supporting files.

Main use cases

1. OpenAPI -> generated REST project

Use generate_project(...) when your input is an OpenAPI YAML or JSON file.

The package parses:

  • x-apigen-project for project-level configuration
  • components.x-apigen-models for domain/entity definitions
  • paths plus x-apigen-binding for route-to-model binding
  • components.schemas for request and response shapes

2. AsyncAPI -> generated event-driven project

Use generate_async_project(...) when your input is already parsed into a Python dict compatible with AsyncAPIProjectSchema.

This flow is intended for event-driven services and supports concepts such as:

  • brokers and servers
  • channels
  • operations
  • message payload schemas
  • entity definitions used during generation

Installation

Install with pip

pip install "git+https://gitlab.com/cloudappi/clo-innova/opendataspace/ods-data-generator-examples.git"

Add it to requirements.txt

git+https://gitlab.com/cloudappi/clo-innova/opendataspace/ods-data-generator-examples.git

Install from a local clone

pip install .

Public API

The package exposes these main entry points:

fromapigen_copierimport (
generate_project,
generate_from_schema,
generate_async_project,
generate_from_async_schema,
)

How to use it in another Python project

The most common integration is:

  1. Add apigen_copier as a dependency
  2. Store an API contract in your project
  3. Call the generator from a Python script, command, or build step
  4. Commit or process the generated output

Example:

fromapigen_copierimportgenerate_projectgenerate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
)

If you want to regenerate an existing generated project and preserve custom code blocks:

fromapigen_copierimportgenerate_projectgenerate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
existing_project_dir="generated/pet-service",
)

Expected input for OpenAPI generation

For generate_project(...), the input must be a YAML or JSON file.

If the file contains openapi or swagger, the package treats it as an OpenAPI specification and parses it automatically.

Minimum recommended structure

openapi: 3.0.0info:
title: Pet APIversion: 1.0.0x-apigen-project:
name: Pet Serviceversion: 1.0.0description: Service generated from OpenAPIdata-driver: postgresqlprefix: /api/v1paths:
/pets:
x-apigen-binding:
model: Petget:
operationId: listPetsresponses:
"200":
description: OKpost:
operationId: createPetrequestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/PetCreate"responses:
"201":
description: Created/pets/{id}:
x-apigen-binding:
model: Petget:
operationId: getPetByIdparameters:
- name: idin: pathrequired: trueschema:
type: stringresponses:
"200":
description: OKcontent:
application/json:
schema:
$ref: "#/components/schemas/PetGet"components:
x-apigen-models:
Pet:
relational-persistence:
table: petsattributes:
- name: idtype: Stringrelational-persistence:
primary-key: trueautogenerated: true
- name: nametype: String
- name: statustype: Stringschemas:
PetGet:
x-apigen-mapping:
model: Petmethod: gettype: objectproperties:
id:
type: stringname:
type: stringstatus:
type: stringPetCreate:
x-apigen-mapping:
model: Petmethod: posttype: objectproperties:
name:
type: stringstatus:
type: string

Input rules that matter

  • x-apigen-project defines the generated project metadata
  • components.x-apigen-models defines the domain models used by the generator
  • each model should define a primary key
  • only operations with x-apigen-binding are turned into generated routers
  • components.schemas is used to infer request and response models
  • data-driver currently accepts values such as postgresql, mysql, oracle, sqlite, mssql, and s3

Expected input for AsyncAPI generation

For generate_async_project(...), the input is a Python dict, not a raw file path.

At minimum, the dictionary should contain:

  • project
  • servers
  • channels
  • operations
  • entities
  • components

Example:

fromapigen_copierimportgenerate_async_projectparsed_data= {
"project": {
"name": "order-events-service",
"version": "1.0.0",
"description": "Async generated service",
"data-driver": "postgresql",
},
"servers": {
"kafka-dev": {
"host": "localhost:9092",
"protocol": "kafka",
"security": [],
}
},
"channels": {
"orderEvents": {
"address": "orders.events",
"parameters": {},
"messages": {},
}
},
"operations": {
"onOrderCreated": {
"action": "receive",
"channel": {
"address": "orders.events",
"parameters": {},
"messages": {},
},
"bindings": {"kafka": {"groupId": "order-service-group"}},
"reply": None,
"messages": [],
}
},
"entities": {
"Order": {
"table": "orders",
"attributes": [
{
"name": "id",
"type": "String",
"relational-persistence": {
"primary-key": True,
"autogenerated": False,
},
}
],
}
},
"components": {
"schemas": {}
},
}
generate_async_project(
parsed_data=parsed_data,
output_dir="generated/order-events-service",
)

What gets generated

Depending on the input and template, the package can generate files such as:

  • project scaffolding
  • domain models
  • route modules
  • repositories
  • services
  • mappers
  • broker configuration
  • DTOs and response models

Regeneration and custom code preservation

One of the important features of this package is regeneration support.

When existing_project_dir is provided, the generator can:

  • extract preserved custom code blocks from the previous project
  • inject them into the regenerated project
  • copy an existing UserCode/ folder into the new output

This makes the package suitable not only for one-time scaffolding, but also for iterative generation workflows.

Typical integration pattern

In a consuming repository, a common setup is:

my-python-project/
├── specs/
│ └── petstore.yaml
├── scripts/
│ └── generate_service.py
├── generated/
│ └── pet-service/
└── pyproject.toml or requirements.txt

Example generator script:

fromapigen_copierimportgenerate_projectdefmain() ->None:
generate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
)
if__name__=="__main__":
main()

Then run:

python scripts/generate_service.py

Summary

apigen_copier is a reusable Python dependency for teams that want to generate backend projects from API contracts instead of writing the initial boilerplate by hand. Its main value is that it turns structured API input into a maintainable project skeleton and supports safe regeneration when the contract evolves.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages