Skip to content

Commit 86c72b6

Browse files
committed
wip: nico helped with dlt
1 parent 5606c3d commit 86c72b6

1 file changed

Lines changed: 78 additions & 106 deletions

File tree

src/datasync/nva.py

Lines changed: 78 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
import datetime
2+
import pathlib
3+
14
import dlt
25
import typer
3-
from dlt.sources.rest_api import rest_api_source
6+
from dlt.destinations.impl.filesystem.factory import filesystem
7+
from dlt.sources.helpers.rest_client import RESTClient
8+
from dlt.sources.helpers.rest_client.paginators import JSONLinkPaginator
49

510
from .settings import (
611
INSTITUTION_CODE,
@@ -12,99 +17,42 @@
1217
app = typer.Typer()
1318

1419

15-
def dlt_source(
16-
year,
17-
resources,
18-
projects,
19-
persons,
20-
categories,
21-
funding_sources,
22-
base_url,
23-
institution_code,
24-
):
25-
if year is None:
26-
log.info("No year specified, syncing all available years.")
27-
resource_params = {
28-
"unit": institution_code,
29-
}
30-
else:
31-
log.info(f"Syncing data for year: {year}")
32-
resource_params = {
33-
"unit": institution_code,
34-
"publicationYearSince": year,
35-
"publicationYearBefore": year + 1,
36-
}
37-
return rest_api_source(
38-
{
39-
"client": {
40-
"base_url": base_url,
41-
"paginator": {
42-
"type": "json_link",
43-
"next_url_path": "nextResults",
44-
},
45-
},
46-
"resources": list(
47-
filter(
48-
lambda r: r is not None,
49-
[
50-
{
51-
"name": "resources",
52-
"max_table_nesting": 0,
53-
"endpoint": {
54-
"path": "search/resources",
55-
"data_selector": "hits",
56-
"params": {
57-
**resource_params,
58-
},
59-
},
60-
}
61-
if resources
62-
else None,
63-
{
64-
"name": "projects",
65-
"max_table_nesting": 0,
66-
"endpoint": {
67-
"path": f"cristin/organization/{institution_code}/projects", # noqa: E501
68-
"data_selector": "hits",
69-
},
70-
}
71-
if projects
72-
else None,
73-
{
74-
"name": "persons",
75-
"max_table_nesting": 0,
76-
"endpoint": {
77-
"path": f"cristin/organization/{institution_code}/persons", # noqa: E501
78-
"data_selector": "hits",
79-
},
80-
}
81-
if persons
82-
else None,
83-
{
84-
"name": "categories",
85-
"max_table_nesting": 0,
86-
"endpoint": {
87-
"path": "cristin/category/project",
88-
"data_selector": "hits",
89-
},
90-
}
91-
if categories
92-
else None,
93-
{
94-
"name": "funding_sources",
95-
"max_table_nesting": 0,
96-
"endpoint": {
97-
"path": "cristin/funding-sources",
98-
"data_selector": "hits",
99-
},
100-
}
101-
if funding_sources
102-
else None,
103-
],
104-
)
105-
),
106-
}
107-
)
20+
# {
21+
# "name": "projects",
22+
# "endpoint": {
23+
# "path": f"cristin/organization/{institution_code}/projects", # noqa: E501
24+
# "data_selector": "hits",
25+
# },
26+
# }
27+
# if projects
28+
# else None,
29+
# {
30+
# "name": "persons",
31+
# "endpoint": {
32+
# "path": f"cristin/organization/{institution_code}/persons", # noqa: E501
33+
# "data_selector": "hits",
34+
# },
35+
# }
36+
# if persons
37+
# else None,
38+
# {
39+
# "name": "categories",
40+
# "endpoint": {
41+
# "path": "cristin/category/project",
42+
# "data_selector": "hits",
43+
# },
44+
# }
45+
# if categories
46+
# else None,
47+
# {
48+
# "name": "funding_sources",
49+
# "endpoint": {
50+
# "path": "cristin/funding-sources",
51+
# "data_selector": "hits",
52+
# },
53+
# }
54+
# if funding_sources
55+
# else None,
10856

10957

11058
@app.command()
@@ -117,25 +65,49 @@ def run(
11765
base_url: str = NVA_BASE_URL,
11866
duckdb_name: str = NVA_DUCKDB_NAME,
11967
institution_code: str = INSTITUTION_CODE,
120-
year: int = None,
12168
):
69+
@dlt.source()
70+
def nva():
71+
client = RESTClient(
72+
base_url=base_url,
73+
paginator=JSONLinkPaginator(next_url_path="nextResults"),
74+
data_selector="hits",
75+
)
76+
77+
def get_resources():
78+
for year in set(range(2025, datetime.datetime.now().year + 1)):
79+
log.debug("Fetching resources for year", year=year)
80+
yield from client.paginate(
81+
"search/resources",
82+
method="get",
83+
params={
84+
"unit": institution_code,
85+
"publicationYearSince": year,
86+
"publicationYearBefore": year + 1,
87+
},
88+
)
89+
90+
yield dlt.resource(
91+
get_resources(),
92+
name="resources",
93+
write_disposition="replace",
94+
max_table_nesting=1,
95+
)
96+
12297
pipeline = dlt.pipeline(
12398
pipeline_name=duckdb_name,
124-
destination="duckdb",
99+
destination=filesystem(
100+
bucket_url="file://"
101+
+ str(pathlib.Path(__name__).absolute().parent / "data"),
102+
layout="{table_name}.{ext}",
103+
),
125104
dataset_name="main",
105+
progress="log",
126106
)
127107

128-
source = dlt_source(
129-
year=year,
130-
resources=resources,
131-
projects=projects,
132-
persons=persons,
133-
categories=categories,
134-
funding_sources=funding_sources,
135-
base_url=base_url,
136-
institution_code=institution_code,
108+
log.info(
109+
pipeline.run(nva(), write_disposition="replace", loader_file_format="parquet")
137110
)
138-
log.info(pipeline.run(source))
139111

140112

141113
if __name__ == "__main__":

0 commit comments

Comments
 (0)