c1groupy 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. c1gpy/__init__.py +0 -0
  2. c1gpy/fastapi_project_files/.gitignore +82 -0
  3. c1gpy/fastapi_project_files/.pre-commit-config.yaml +43 -0
  4. c1gpy/fastapi_project_files/Dockerfile +47 -0
  5. c1gpy/fastapi_project_files/README.md.template +161 -0
  6. c1gpy/fastapi_project_files/docker-compose.yml +12 -0
  7. c1gpy/fastapi_project_files/pyproject.toml.template +21 -0
  8. c1gpy/fastapi_project_files/src/__init__.py +0 -0
  9. c1gpy/fastapi_project_files/src/api_interface.py +55 -0
  10. c1gpy/fastapi_project_files/src/endpoints/__init__.py +0 -0
  11. c1gpy/fastapi_project_files/src/endpoints/router1/__init__.py +0 -0
  12. c1gpy/fastapi_project_files/src/endpoints/router1/example_endpoint.py +24 -0
  13. c1gpy/fastapi_project_files/src/endpoints/router2/__init__.py +0 -0
  14. c1gpy/fastapi_project_files/src/endpoints/router2/example_endpoint.py +24 -0
  15. c1gpy/fastapi_project_files/src/entrypoint.sh +17 -0
  16. c1gpy/fastapi_project_files/src/routers/__init__.py +0 -0
  17. c1gpy/fastapi_project_files/src/routers/router1.py +53 -0
  18. c1gpy/fastapi_project_files/src/routers/router2.py +36 -0
  19. c1gpy/fastapi_project_files/tests/__init__.py +0 -0
  20. c1gpy/fastapi_project_files/tests/test_example.py +33 -0
  21. c1gpy/google-utils.py +659 -0
  22. c1gpy/init_fastapi_project.py +198 -0
  23. c1gpy/init_streamlit_project.py +190 -0
  24. c1gpy/llm.py +8 -0
  25. c1gpy/logging.py +246 -0
  26. c1gpy/streamlit_project_files/.gitignore +82 -0
  27. c1gpy/streamlit_project_files/.pre-commit-config.yaml +43 -0
  28. c1gpy/streamlit_project_files/Dockerfile +47 -0
  29. c1gpy/streamlit_project_files/README.md.template +106 -0
  30. c1gpy/streamlit_project_files/docker-compose.yml +12 -0
  31. c1gpy/streamlit_project_files/pyproject.toml.template +19 -0
  32. c1gpy/streamlit_project_files/src/app/App.py.template +21 -0
  33. c1gpy/streamlit_project_files/src/app/__init__.py +0 -0
  34. c1gpy/streamlit_project_files/src/app/pages/1_Page_1.py +9 -0
  35. c1gpy/streamlit_project_files/src/app/pages/2_Page_2.py +15 -0
  36. c1gpy/streamlit_project_files/src/app/pages/__init__.py +0 -0
  37. c1gpy/streamlit_project_files/src/app/pages/home.py +27 -0
  38. c1gpy/streamlit_project_files/src/entrypoint.sh +33 -0
  39. c1gpy/streamlit_project_files/tests/__init__.py +0 -0
  40. c1gpy/streamlit_project_files/tests/test_example.py +8 -0
  41. c1gpy/utils.py +207 -0
  42. c1groupy-0.3.0.dist-info/METADATA +604 -0
  43. c1groupy-0.3.0.dist-info/RECORD +46 -0
  44. c1groupy-0.3.0.dist-info/WHEEL +4 -0
  45. c1groupy-0.3.0.dist-info/entry_points.txt +4 -0
  46. c1groupy-0.3.0.dist-info/licenses/LICENCE +21 -0
c1gpy/__init__.py ADDED
File without changes
@@ -0,0 +1,82 @@
1
+ # Project-specific
2
+ *secret*
3
+ *secret*/
4
+ *.json
5
+ *.xlsx
6
+ *.xml
7
+ *.csv
8
+ *cache*
9
+ *.zip
10
+ input/
11
+ data_files/
12
+ duckdb
13
+ .env
14
+
15
+ # Python
16
+ __pycache__/
17
+ *.py[cod]
18
+ *$py.class
19
+ *.so
20
+ .Python
21
+
22
+ # Distribution / packaging
23
+ build/
24
+ develop-eggs/
25
+ dist/
26
+ downloads/
27
+ eggs/
28
+ .eggs/
29
+ lib/
30
+ lib64/
31
+ parts/
32
+ sdist/
33
+ var/
34
+ wheels/
35
+ *.egg-info/
36
+ .installed.cfg
37
+ *.egg
38
+ MANIFEST
39
+
40
+ # Virtual environments
41
+ venv/
42
+ ENV/
43
+ env/
44
+ .venv/
45
+
46
+ # Testing
47
+ .pytest_cache/
48
+ .coverage
49
+ .coverage.*
50
+ htmlcov/
51
+ .tox/
52
+ .nox/
53
+ *.cover
54
+ .hypothesis/
55
+
56
+ # Type checking
57
+ .mypy_cache/
58
+ .dmypy.json
59
+ dmypy.json
60
+ .pytype/
61
+ .pyre/
62
+
63
+ # IDEs
64
+ .DS_Store
65
+ .vscode/
66
+ .idea/
67
+ *.swp
68
+ *.swo
69
+ *~
70
+ .project
71
+ .pydevproject
72
+ .settings/
73
+
74
+ # Jupyter Notebook
75
+ .ipynb_checkpoints
76
+
77
+ # Documentation
78
+ docs/_build/
79
+ site/
80
+
81
+ # Streamlit
82
+ .streamlit/
@@ -0,0 +1,43 @@
1
+ # pre commit hook config
2
+ repos:
3
+ - repo: https://github.com/pre-commit/pre-commit-hooks
4
+ rev: v5.0.0
5
+ hooks:
6
+ - id: check-yaml
7
+ stages: [pre-commit]
8
+ - id: end-of-file-fixer
9
+ stages: [pre-commit]
10
+ - id: trailing-whitespace
11
+ stages: [pre-commit]
12
+ - id: detect-private-key
13
+ stages: [pre-commit]
14
+ - id: check-added-large-files
15
+ stages: [pre-commit]
16
+
17
+ - repo: https://github.com/python-poetry/poetry
18
+ rev: 2.1.1
19
+ hooks:
20
+ - id: poetry-check
21
+ stages: [pre-commit]
22
+ - id: poetry-lock
23
+ stages: [pre-commit]
24
+
25
+ - repo: https://github.com/astral-sh/ruff-pre-commit
26
+ # Ruff version.
27
+ rev: v0.11.2
28
+ hooks:
29
+ # Run the linter.
30
+ - id: ruff
31
+ args: [ --fix]
32
+ # Run the formatter.
33
+ - id: ruff-format
34
+
35
+ # pre push needs install of podman & podman-compose
36
+ - repo: local
37
+ hooks:
38
+ - id: run-unit-tests
39
+ name: Run unit tests in container
40
+ entry: bash -c 'PYTEST=TRUE podman-compose up --build --force-recreate --remove-orphans'
41
+ language: system
42
+ stages: [pre-push]
43
+ verbose: true
@@ -0,0 +1,47 @@
1
+ FROM python:3.12-slim AS builder
2
+
3
+ WORKDIR /app
4
+
5
+ # Install uv
6
+ RUN pip install --no-cache-dir uv
7
+
8
+ # Copy only dependency files first
9
+ COPY pyproject.toml ./
10
+
11
+ # Install dependencies using uv
12
+ RUN uv pip install --system -e .
13
+
14
+ # use multi stage for smaller image size
15
+ FROM python:3.12-slim
16
+
17
+ LABEL author="{author_email}"
18
+
19
+ WORKDIR /app
20
+
21
+ # Copy uv and installed packages from builder
22
+ COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
23
+ COPY --from=builder /usr/local/bin /usr/local/bin
24
+
25
+ # Create non-root user
26
+ RUN useradd -m -u 1000 appuser
27
+
28
+ # Copy project files
29
+ COPY pyproject.toml ./
30
+ COPY src/ ./src/
31
+ COPY tests/ ./tests/
32
+
33
+ # Change ownership of src and tests to appuser
34
+ RUN chown -R appuser:appuser /app/src /app/tests
35
+
36
+ # Make entrypoint executable
37
+ RUN chmod +x /app/src/entrypoint.sh
38
+
39
+ # Switch to non-root user
40
+ USER appuser
41
+
42
+ # Set default environment variables
43
+ ENV LOCALRUN=FALSE
44
+ ENV PYTEST=FALSE
45
+
46
+ #needs $PORT $LOCALRUN $PYTEST
47
+ ENTRYPOINT ["/app/src/entrypoint.sh"]
@@ -0,0 +1,161 @@
1
+ # {project_name}
2
+
3
+ A FastAPI application with organized router structure.
4
+
5
+ ## Project Structure
6
+
7
+ ```
8
+ {project_name}/
9
+ ├── src/
10
+ │ ├── api_interface.py # Main FastAPI app
11
+ │ ├── routers/ # API routers
12
+ │ │ ├── router1.py
13
+ │ │ └── router2.py
14
+ │ ├── endpoints/ # Endpoint logic
15
+ │ │ ├── router1/
16
+ │ │ │ └── example_endpoint.py
17
+ │ │ └── router2/
18
+ │ │ └── example_endpoint.py
19
+ │ └── entrypoint.sh # Container entrypoint script
20
+ ├── tests/ # Test files
21
+ ├── Dockerfile # Docker configuration
22
+ ├── docker-compose.yml # Docker Compose configuration
23
+ ├── pyproject.toml # Project dependencies
24
+ ├── .pre-commit-config.yaml # Pre-commit hooks
25
+ └── .gitignore # Git ignore rules
26
+ ```
27
+
28
+ ## Getting Started
29
+
30
+ ### Local Development (with uv)
31
+
32
+ 1. Install dependencies:
33
+ ```bash
34
+ uv sync
35
+ ```
36
+
37
+ 2. Run the application:
38
+ ```bash
39
+ uv run hypercorn src.api_interface:rest_api --bind :8000 --reload
40
+ ```
41
+
42
+ The API will be available at:
43
+ - **API**: http://localhost:8000
44
+ - **Interactive Docs**: http://localhost:8000/docs
45
+ - **ReDoc**: http://localhost:8000/redoc
46
+
47
+ ### Docker Development
48
+
49
+ 1. Build and run with Docker Compose:
50
+ ```bash
51
+ docker-compose up --build --force-recreate --remove-orphans
52
+ ```
53
+
54
+ The application will be available at http://localhost:8000
55
+
56
+ The `LOCALRUN=TRUE` environment variable enables hot-reloading for development.
57
+
58
+ ### Production Deployment
59
+
60
+ For production, set `LOCALRUN=FALSE` in the docker-compose.yml or use the Dockerfile directly:
61
+
62
+ ```bash
63
+ docker build -t {project_name} .
64
+ docker run -p 8000:8000 -e LOCALRUN=FALSE -e PORT=8000 {project_name}
65
+ ```
66
+
67
+ ## Running Tests
68
+
69
+ ### Locally
70
+ ```bash
71
+ uv run pytest tests/
72
+ ```
73
+
74
+ ### In Docker
75
+ ```bash
76
+ docker-compose run -e PYTEST=TRUE fastapi-app
77
+ ```
78
+
79
+ ## API Structure
80
+
81
+ ### Routers
82
+
83
+ Routers are defined in `src/routers/` and organize related endpoints:
84
+
85
+ - **router1.py**: Example router with basic CRUD operations
86
+ - **router2.py**: Example router with data processing endpoints
87
+
88
+ ### Endpoints
89
+
90
+ Endpoint logic is separated into `src/endpoints/` for better organization:
91
+
92
+ - **router1/**: Business logic for router1 endpoints
93
+ - **router2/**: Business logic for router2 endpoints
94
+
95
+ ### Adding New Endpoints
96
+
97
+ 1. Create endpoint logic in `src/endpoints/router_name/`:
98
+ ```python
99
+ # src/endpoints/router1/new_endpoint.py
100
+ async def get_data() -> dict:
101
+ return {{"data": "example"}}
102
+ ```
103
+
104
+ 2. Add route in `src/routers/router1.py`:
105
+ ```python
106
+ from endpoints.router1 import new_endpoint
107
+
108
+ @router.get("/data")
109
+ async def get_data():
110
+ return await new_endpoint.get_data()
111
+ ```
112
+
113
+ ### Adding New Routers
114
+
115
+ 1. Create router file in `src/routers/router3.py`:
116
+ ```python
117
+ from fastapi import APIRouter
118
+
119
+ router = APIRouter(prefix="/router3", tags=["router3"])
120
+
121
+ @router.get("/example")
122
+ async def example():
123
+ return {{"message": "Hello from router3"}}
124
+ ```
125
+
126
+ 2. Register in `src/api_interface.py`:
127
+ ```python
128
+ from routers import router1, router2, router3
129
+
130
+ rest_api.include_router(router3.router)
131
+ ```
132
+
133
+ ## API Security
134
+
135
+ The template includes commented-out API key authentication:
136
+
137
+ ```python
138
+ # Uncomment in routers to enable
139
+ from fastapi.security import APIKeyHeader
140
+ api_key_header = APIKeyHeader(name="X-API-Key", auto_error=False)
141
+
142
+ @router.get("/secure")
143
+ async def secure_endpoint(api_key: str = Security(api_key_header)):
144
+ # Validate api_key
145
+ return {{"secure": "data"}}
146
+ ```
147
+
148
+ ## Environment Variables
149
+
150
+ - `PORT`: Port for the API server (default: 8000)
151
+ - `LOCALRUN`: Set to `TRUE` for development mode with hot-reloading (default: `FALSE`)
152
+ - `PYTEST`: Set to `TRUE` to run tests instead of the app (default: `FALSE`)
153
+
154
+ ## Pre-commit Hooks
155
+
156
+ Install pre-commit hooks:
157
+ ```bash
158
+ pre-commit install
159
+ ```
160
+
161
+ This will run linting and formatting checks before each commit.
@@ -0,0 +1,12 @@
1
+ services:
2
+ fastapi-app:
3
+ build: .
4
+ ports:
5
+ - "8000:8000"
6
+ environment:
7
+ - LOCALRUN=TRUE
8
+ - PYTEST=FALSE
9
+ - PORT=8000
10
+ volumes:
11
+ - ./src:/app/src
12
+ restart: unless-stopped
@@ -0,0 +1,21 @@
1
+ [project]
2
+ name = "{project_name}"
3
+ version = "0.1.0"
4
+ description = "A FastAPI application"
5
+ authors = [
6
+ {{email = "{author_email}"}},
7
+ ]
8
+ requires-python = ">=3.12"
9
+ dependencies = [
10
+ "fastapi>=0.115.0",
11
+ "hypercorn[uvloop]>=0.17.0",
12
+ "pytest>=8.0.0",
13
+ "httpx>=0.27.0",
14
+ ]
15
+
16
+ [tool.uv]
17
+ dev-dependencies = []
18
+
19
+ [build-system]
20
+ requires = ["hatchling"]
21
+ build-backend = "hatchling.build"
File without changes
@@ -0,0 +1,55 @@
1
+ """Main FastAPI application interface."""
2
+
3
+ from fastapi import FastAPI
4
+ from fastapi.middleware.cors import CORSMiddleware
5
+
6
+ from routers import router1, router2
7
+
8
+ # Initialize FastAPI app
9
+ rest_api = FastAPI(
10
+ title="{project_name}",
11
+ description="FastAPI application with multiple routers",
12
+ version="0.1.0",
13
+ docs_url="/docs",
14
+ redoc_url="/redoc",
15
+ contact={
16
+ {
17
+ "email": "{author_email}",
18
+ }
19
+ },
20
+ )
21
+
22
+ # Configure CORS
23
+ rest_api.add_middleware(
24
+ CORSMiddleware,
25
+ allow_origins=["*"], # Configure appropriately for production
26
+ allow_credentials=True,
27
+ allow_methods=["*"],
28
+ allow_headers=["*"],
29
+ )
30
+
31
+ # Include routers
32
+ rest_api.include_router(router1.router)
33
+ rest_api.include_router(router2.router)
34
+
35
+
36
+ @rest_api.get("/")
37
+ async def root() -> dict:
38
+ """
39
+ Root endpoint.
40
+
41
+ Returns:
42
+ dict: Welcome message
43
+ """
44
+ return {{"message": "Welcome to {{project_name}}", "docs": "/docs"}}
45
+
46
+
47
+ @rest_api.get("/health")
48
+ async def health_check() -> dict:
49
+ """
50
+ Health check endpoint.
51
+
52
+ Returns:
53
+ dict: Health status
54
+ """
55
+ return {{"status": "healthy", "service": "{{project_name}}"}}
File without changes
@@ -0,0 +1,24 @@
1
+ """Example endpoint for router1."""
2
+
3
+
4
+ async def get_example_data() -> dict:
5
+ """
6
+ Example async endpoint function.
7
+
8
+ Returns:
9
+ dict: Example data
10
+ """
11
+ return {"message": "Hello from router1", "status": "success"}
12
+
13
+
14
+ async def create_example_item(item_data: dict) -> dict:
15
+ """
16
+ Example async POST endpoint function.
17
+
18
+ Args:
19
+ item_data: Data for the new item
20
+
21
+ Returns:
22
+ dict: Created item with ID
23
+ """
24
+ return {"id": 1, "data": item_data, "status": "created"}
@@ -0,0 +1,24 @@
1
+ """Example endpoint for router2."""
2
+
3
+
4
+ async def get_status() -> dict:
5
+ """
6
+ Example async endpoint function.
7
+
8
+ Returns:
9
+ dict: Status information
10
+ """
11
+ return {"status": "healthy", "service": "router2"}
12
+
13
+
14
+ async def process_data(data: dict) -> dict:
15
+ """
16
+ Example async data processing endpoint.
17
+
18
+ Args:
19
+ data: Input data to process
20
+
21
+ Returns:
22
+ dict: Processed result
23
+ """
24
+ return {"processed": True, "input": data, "result": "processed successfully"}
@@ -0,0 +1,17 @@
1
+ #!/bin/bash
2
+ ## Main script for starting up FastAPI WSGI server or tests in a container
3
+
4
+ # Redirect stderr to stdout for better logging
5
+ exec 2>&1
6
+
7
+ if [ "${PYTEST}" = 'TRUE' ]
8
+ then
9
+ python -m pytest -v tests/ # run Pytest framework
10
+ else # run FastAPI
11
+ if [ "${LOCALRUN}" = 'TRUE' ]
12
+ then
13
+ python -m hypercorn api_interface:rest_api --bind :$PORT --reload --workers 4 --worker-class uvloop # run with reload for local dev
14
+ else
15
+ python -m hypercorn api_interface:rest_api --bind :$PORT --workers 4 --worker-class uvloop
16
+ fi
17
+ fi
File without changes
@@ -0,0 +1,53 @@
1
+ """Router1 - Example API routes."""
2
+
3
+ from fastapi import APIRouter # , Security
4
+ # from fastapi.security import APIKeyHeader
5
+
6
+ from endpoints.router1 import example_endpoint
7
+
8
+ router = APIRouter(prefix="/router1", tags=["router1"])
9
+
10
+ # Uncomment to enable API key authentication
11
+ # api_key_header = APIKeyHeader(name="X-API-Key", auto_error=False)
12
+
13
+
14
+ @router.get("/example")
15
+ async def get_example() -> dict:
16
+ """
17
+ Get example data.
18
+
19
+ Returns:
20
+ dict: Example response
21
+ """
22
+ return await example_endpoint.get_example_data()
23
+
24
+
25
+ @router.post("/items")
26
+ async def create_item(item_data: dict) -> dict:
27
+ """
28
+ Create a new item.
29
+
30
+ Args:
31
+ item_data: Item data to create
32
+
33
+ Returns:
34
+ dict: Created item
35
+ """
36
+ return await example_endpoint.create_example_item(item_data)
37
+
38
+
39
+ # Example with API key security (commented out)
40
+ # @router.get("/secure")
41
+ # async def secure_endpoint(api_key: str = Security(api_key_header)):
42
+ # """
43
+ # Secure endpoint requiring API key.
44
+ #
45
+ # Args:
46
+ # api_key: API key from header
47
+ #
48
+ # Returns:
49
+ # dict: Secure data
50
+ # """
51
+ # if api_key != "your-secret-key":
52
+ # raise HTTPException(status_code=403, detail="Invalid API key")
53
+ # return {"message": "Access granted", "secure_data": "sensitive information"}
@@ -0,0 +1,36 @@
1
+ """Router2 - Example API routes."""
2
+
3
+ from fastapi import APIRouter # , Security
4
+ # from fastapi.security import APIKeyHeader
5
+
6
+ from endpoints.router2 import example_endpoint
7
+
8
+ router = APIRouter(prefix="/router2", tags=["router2"])
9
+
10
+ # Uncomment to enable API key authentication
11
+ # api_key_header = APIKeyHeader(name="X-API-Key", auto_error=False)
12
+
13
+
14
+ @router.get("/status")
15
+ async def get_status() -> dict:
16
+ """
17
+ Get service status.
18
+
19
+ Returns:
20
+ dict: Status information
21
+ """
22
+ return await example_endpoint.get_status()
23
+
24
+
25
+ @router.post("/process")
26
+ async def process_data(data: dict) -> dict:
27
+ """
28
+ Process input data.
29
+
30
+ Args:
31
+ data: Data to process
32
+
33
+ Returns:
34
+ dict: Processing result
35
+ """
36
+ return await example_endpoint.process_data(data)
File without changes
@@ -0,0 +1,33 @@
1
+ from fastapi.testclient import TestClient
2
+
3
+ from api_interface import rest_api
4
+
5
+ client = TestClient(rest_api)
6
+
7
+
8
+ def test_root():
9
+ """Test root endpoint."""
10
+ response = client.get("/")
11
+ assert response.status_code == 200
12
+ assert "message" in response.json()
13
+
14
+
15
+ def test_health_check():
16
+ """Test health check endpoint."""
17
+ response = client.get("/health")
18
+ assert response.status_code == 200
19
+ assert response.json()["status"] == "healthy"
20
+
21
+
22
+ def test_router1_example():
23
+ """Test router1 example endpoint."""
24
+ response = client.get("/router1/example")
25
+ assert response.status_code == 200
26
+ assert response.json()["status"] == "success"
27
+
28
+
29
+ def test_router2_status():
30
+ """Test router2 status endpoint."""
31
+ response = client.get("/router2/status")
32
+ assert response.status_code == 200
33
+ assert response.json()["status"] == "healthy"